Description
scripts/vbw-statusline.sh queries the macOS keychain at line 739 with the literal service name Claude Code-credentials:
CRED_JSON=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)
Newer Claude Code installs persist OAuth credentials under per-install suffixed service names — e.g. Claude Code-credentials-126018b2. The literal-name lookup therefore fails with errSecItemNotFound (exit code 44), not a real access denial.
When no .credentials.json fallback file is present and claude auth status --json reports authMethod=claude.ai, control falls through to scripts/vbw-statusline.sh:964-965:
elif [ "$AUTH_METHOD" = "claude.ai" ]; then
USAGE_LINE="${D}Limits: keychain access denied (allow Terminal in Keychain Access.app or set VBW_OAUTH_TOKEN)${X}"
The message blames a permissions denial that didn't happen, and suggests an action ("allow Terminal in Keychain Access.app") that cannot fix the actual problem (item-not-found under that exact name).
/vbw command that triggered it
/vbw:debug (statusline rendering — visible whenever statusline_hide_limits=false and the user is logged in via claude.ai OAuth on macOS).
Reproduction
- macOS, Claude Code installed and logged in via
claude.ai OAuth.
.vbw-planning/config.json has statusline_hide_limits: false.
- No
VBW_OAUTH_TOKEN env var; no .credentials.json files at $HOME/.config/claude-code/, $HOME/.claude/, or $CLAUDE_CONFIG_DIR.
- Confirm:
security find-generic-password -s "Claude Code-credentials" -w 2>&1 → SecKeychainSearchCopyNext: The specified item could not be found in the keychain. (exit 44).
- Confirm suffixed items exist:
security dump-keychain 2>/dev/null | grep -o '"svce"<blob>="Claude Code-credentials[^"]*"' | sort -u → multiple Claude Code-credentials-<8hex> entries.
- Run the statusline; the Limits line shows
keychain access denied (allow Terminal in Keychain Access.app or set VBW_OAUTH_TOKEN).
Environment
- macOS Darwin
- VBW version 1.36.1
- Claude Code 2.1.126
Proposed fix
Two-part change in scripts/vbw-statusline.sh:
- Suffixed-name lookup. Try the literal
Claude Code-credentials first (back-compat); if missing, probe a narrow set of suffixed candidates discovered via a non-prompting security dump-keychain filter, taking the first whose .claudeAiOauth.accessToken parses.
- Exit-code-aware messaging. Capture the
security exit code instead of swallowing stderr unconditionally:
44 (errSecItemNotFound) → Limits: OAuth token unavailable (run /login or set VBW_OAUTH_TOKEN)
51 (errSecAuthFailed) → keep the existing "keychain access denied" wording (it's accurate in that case).
BATS coverage to add:
- Literal-name path still works when the unsuffixed item exists.
- Suffixed-name path hits when only suffixed items exist.
- Exit 44 produces the "OAuth token unavailable" message.
- Exit 51 still produces the "keychain access denied" message.
Description
scripts/vbw-statusline.shqueries the macOS keychain at line 739 with the literal service nameClaude Code-credentials:CRED_JSON=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)Newer Claude Code installs persist OAuth credentials under per-install suffixed service names — e.g.
Claude Code-credentials-126018b2. The literal-name lookup therefore fails witherrSecItemNotFound(exit code 44), not a real access denial.When no
.credentials.jsonfallback file is present andclaude auth status --jsonreportsauthMethod=claude.ai, control falls through toscripts/vbw-statusline.sh:964-965:The message blames a permissions denial that didn't happen, and suggests an action ("allow Terminal in Keychain Access.app") that cannot fix the actual problem (item-not-found under that exact name).
/vbw command that triggered it
/vbw:debug(statusline rendering — visible wheneverstatusline_hide_limits=falseand the user is logged in via claude.ai OAuth on macOS).Reproduction
claude.aiOAuth..vbw-planning/config.jsonhasstatusline_hide_limits: false.VBW_OAUTH_TOKENenv var; no.credentials.jsonfiles at$HOME/.config/claude-code/,$HOME/.claude/, or$CLAUDE_CONFIG_DIR.security find-generic-password -s "Claude Code-credentials" -w 2>&1→SecKeychainSearchCopyNext: The specified item could not be found in the keychain.(exit 44).security dump-keychain 2>/dev/null | grep -o '"svce"<blob>="Claude Code-credentials[^"]*"' | sort -u→ multipleClaude Code-credentials-<8hex>entries.keychain access denied (allow Terminal in Keychain Access.app or set VBW_OAUTH_TOKEN).Environment
Proposed fix
Two-part change in
scripts/vbw-statusline.sh:Claude Code-credentialsfirst (back-compat); if missing, probe a narrow set of suffixed candidates discovered via a non-promptingsecurity dump-keychainfilter, taking the first whose.claudeAiOauth.accessTokenparses.securityexit code instead of swallowing stderr unconditionally:44(errSecItemNotFound) →Limits: OAuth token unavailable (run /login or set VBW_OAUTH_TOKEN)51(errSecAuthFailed) → keep the existing "keychain access denied" wording (it's accurate in that case).BATS coverage to add: