Merge request links that never sync are re-read every minute forever, flooding macOS with keychain prompts#31954

opened6d agobySsndrnz

What happened

On macOS, a "security wants to use the "login" keychain" password dialog kept reappearing while T3 Code was open. Cancelling it or entering the password only brought it back. New threads failed with Claude's "Not logged in · Please run /login" while it was open. Only quitting T3 Code stopped it.

Diagnosis

13 threads link GitLab MRs on a self-managed GitLab served under /gitlab. Because of #20226 each is stored as gitlab/group/project, so every read fails with Merge request not found and no link ever gets a snapshot.

PullRequestSyncReactor retries them without limit:

  • isDue returns true for any link with a null snapshot, and lastSyncedAt is only set after a successful read (L564). A never-synced link is re-read every 1-minute sweep, with no backoff or cap.
  • Each summary read starts several glab calls in parallel; one failure interrupts its siblings and the next sweep starts them all again. With 13 links: ~236 glab runs/min, 63% interrupted after ~300 ms.
  • glab stored its token in the OS keyring (use_keyring: true, the glab auth login default). Every run reads it through /usr/bin/security, so each run can open a keychain dialog. They arrive faster than anyone can answer, and while one is open other keychain reads stall, including the Claude CLI's login lookup.

Unlinking doesn't help: linkCreatedChangeRequests re-links every MR an agent creates with glab mr create, and agents link MRs themselves. No setting turns either off.

Any read that keeps failing (wrong path, revoked access, deleted MR) causes the same endless retries; #20226 is just how this user hit it.

Steps to reproduce

  1. macOS, glab logged in to a self-managed GitLab served under a path prefix, default keyring storage.
  2. Link an MR from that instance to a thread, or let an agent run glab mr create.
  3. Leave T3 open. server.trace.ndjson shows glab runs every sweep and keychain dialogs appear.

Version

T3 Code Desktop 0.1.8-nightly.20261106.4262 (commit c55db3e9). No later commit on main touches this code.

Environment

macOS 27.2 (arm64), Node 24.22.1, glab 1.128.0, Claude Code 2.1.318. Desktop app with its local server.

Evidence

shell
1- Trace: 728 `processRunner.runProcessCore {process.command: glab}` spans in ~3 min, 509 `Interrupted`.
2- Repeated: `VcsProcessExitError: VCS process failed in GitLabCli.execute: glab (...) exited with 1 - Merge request not found.`
3- Repeated: `pull request sync skipped {count: 57, reason: "Pull request operation summary failed: GitLab CLI command failed."}`
4- `projection_thread_pull_requests`: 13 rows on that host, all `snapshot_json IS NULL`, `repository` starting with `gitlab/`.
  • #20226: the wrong project path that makes every read fail. This issue is the endless retry that follows; fixing #20226 removes this trigger but not the missing backoff.- #13912: same kind of keychain prompt loop from the background git fetch (backs off, never stops).

Fix applied or workaround

glab auth login --hostname <host> --insecure-storage stores the token in glab's config file instead of the keychain. Dialogs stop; the retries continue.

Filed by

Claude Opus 5.5 (Claude Code) via t3 triage