Summary
Opening the new-thread composer (new thread or new project) starts a background git fetch --all --prune on the project source. With a passphrase-protected ssh key that is not loaded in an agent and SSH_ASKPASS configured, that fetch pops a GUI passphrase dialog on every composer visit, without any user action behind it. I expected a background refresh to never surface a credential prompt; prompts should come only from explicit actions such as opening the branch picker.
Versions and environment
- bb 0.40.0 (desktop app), macOS 26 (Darwin 25.5.0)
- ssh key protected by a passphrase, deliberately not persisted to the agent;
SSH_ASKPASS points at a GUI helper, SSH_ASKPASS_REQUIRE=force
- Project source is a local checkout whose
origin is an ssh remote
Steps to reproduce
- Configure git to reach
origin over ssh with a passphrase-protected key that is not loaded in ssh-agent, and set SSH_ASKPASS to a GUI helper.
- Create a bb project from that checkout.
- Open the new-thread composer for the project (or create a new project and land on its composer).
- A passphrase dialog appears immediately, before touching the branch picker or any other control.
Repeats on every composer visit once the daemon's 30-second fetch throttle has expired. Did not reproduce with the key loaded in the agent (fetch succeeds silently), which is what hides this from most setups.
Expected vs actual
Actual: GUI passphrase prompt on composer load, no user action behind it. Dismissing it leaves the refs unrefreshed; the composer otherwise works.
Expected: no credential prompt from a background refresh. Fetching (and prompting) only when I ask for fresh refs, e.g. opening the branch picker or `bb project branches --refresh`.
Note the failure mode is environment-dependent, which is why this is rarely seen:
- Desktop-app-launched daemon without `SSH_ASKPASS` (no controlling tty, stdin ignored): ssh cannot open `/dev/tty`; the background fetch already fails silently today.
- Terminal-launched daemon: ssh reads the passphrase from that terminal's `/dev/tty`; git blocks until the 5s refresh timeout kills it.
- `SSH_ASKPASS` set in the daemon's environment (mine is system-wide, so the desktop-launched daemon inherits it): the GUI dialog reported here.
The background refresh cannot succeed for this key setup in any of these cases — its result is already discarded and errors swallowed — so the prompt buys nothing.
Evidence
Call path, at f4bbc2fe8:
fetchRemoteBranches is the only network-touching git call on this path; every other read is local (for-each-ref, symbolic-ref, rev-parse). The worktree provisioning fetch sets GIT_TERMINAL_PROMPT=0 (https://github.com/get-bb/bb/blob/f4bbc2fe8/packages/host-workspace/src/provisioning.ts#L406), but that only suppresses git's own credential prompt, not the ssh passphrase, and the branch-refresh fetch sets neither.
What you ruled out
AGENT GENERATED — drafted by Claude Code in a local session; no public report link. Reproduction and code-path verification reviewed by the reporter.
Suggested priority and effort (optional)
Low: hits passphrase-key-without-agent setups only, but each composer visit costs a prompt or a 5s stall with no workaround short of changing key management; fix is small and daemon-local, PR ready.
Checks
Summary
Opening the new-thread composer (new thread or new project) starts a background
git fetch --all --pruneon the project source. With a passphrase-protected ssh key that is not loaded in an agent andSSH_ASKPASSconfigured, that fetch pops a GUI passphrase dialog on every composer visit, without any user action behind it. I expected a background refresh to never surface a credential prompt; prompts should come only from explicit actions such as opening the branch picker.Versions and environment
SSH_ASKPASSpoints at a GUI helper,SSH_ASKPASS_REQUIRE=forceoriginis an ssh remoteSteps to reproduce
originover ssh with a passphrase-protected key that is not loaded inssh-agent, and setSSH_ASKPASSto a GUI helper.Repeats on every composer visit once the daemon's 30-second fetch throttle has expired. Did not reproduce with the key loaded in the agent (fetch succeeds silently), which is what hides this from most setups.
Expected vs actual
Evidence
Call path, at
f4bbc2fe8:refresh=backgroundon load: https://github.com/get-bb/bb/blob/f4bbc2fe8/apps/app/src/hooks/queries/project-queries.ts#L111-L116 (mounted fromNewThreadComposer: https://github.com/get-bb/bb/blob/f4bbc2fe8/apps/app/src/components/promptbox/NewThreadComposer.tsx#L660)host.inspect_git_source { remoteRefresh: "background" }: https://github.com/get-bb/bb/blob/f4bbc2fe8/apps/server/src/routes/projects.ts#L837-L846backgroundandblocking: https://github.com/get-bb/bb/blob/f4bbc2fe8/apps/host-daemon/src/command-handlers/host-branches.ts#L253-L260fetchRemoteBranchesis the only network-touching git call on this path; every other read is local (for-each-ref,symbolic-ref,rev-parse). The worktree provisioning fetch setsGIT_TERMINAL_PROMPT=0(https://github.com/get-bb/bb/blob/f4bbc2fe8/packages/host-workspace/src/provisioning.ts#L406), but that only suppresses git's own credential prompt, not the ssh passphrase, and the branch-refresh fetch sets neither.What you ruled out
remoteRefresh: "background"means "do not wait for the fetch", not "do not fetch" — the enum has no non-fetching value forhost.inspect_git_source(https://github.com/get-bb/bb/blob/f4bbc2fe8/packages/host-daemon-contract/src/commands.ts#L754).Suggested priority and effort (optional)
Low: hits passphrase-key-without-agent setups only, but each composer visit costs a prompt or a 5s stall with no workaround short of changing key management; fix is small and daemon-local, PR ready.
Checks
main, or I say above that I could not.> AGENT GENERATEDand links the thread or report.