Skip to content

fix: support hash-suffixed macOS Keychain service name#14

Closed
xicv wants to merge 3 commits into
tylergraydev:mainfrom
xicv:main
Closed

fix: support hash-suffixed macOS Keychain service name#14
xicv wants to merge 3 commits into
tylergraydev:mainfrom
xicv:main

Conversation

@xicv

@xicv xicv commented Feb 13, 2026

Copy link
Copy Markdown

Summary

  • Claude Code now stores credentials under a hash-suffixed keychain service name (e.g. Claude Code-credentials-697375ae) instead of the previous Claude Code-credentials
  • This caused 401 Unauthorized errors when fetching usage data, since the tool was reading stale tokens from the old keychain entry
  • The fix dynamically discovers the correct keychain service name by searching for all matching entries and preferring the most specific (longest) one, with a fallback to the legacy name

Changes

Refactored getOAuthTokenMacOS() in src/utils/oauth.ts into smaller focused functions:

  • findKeychainServiceName() — searches the keychain for all Claude Code-credentials* entries and returns the longest match (the one with the hash suffix)
  • readKeychainContent() — reads and returns content from a given keychain service
  • extractTokenFromKeychainContent() — parses the OAuth token from keychain JSON content

Falls back to the legacy Claude Code-credentials name if the suffixed entry fails, so it remains backwards-compatible.

Test plan

  • Verified locally on macOS with both old (Claude Code-credentials) and new (Claude Code-credentials-697375ae) keychain entries present
  • Confirmed usage API returns real data (7% five-hour, 9% weekly) after the fix, where it previously returned 401 Unauthorized
  • Confirmed fallback to legacy name works when no suffixed entry exists

xicvv and others added 3 commits February 13, 2026 16:13
Claude Code now stores credentials under a hash-suffixed keychain
service name (e.g. "Claude Code-credentials-697375ae") instead of
the previous "Claude Code-credentials". This caused 401 Unauthorized
errors when fetching usage data since the tool was reading stale
tokens from the old entry.

The fix dynamically discovers the correct keychain service name by
searching for all matching entries and preferring the most specific
(longest) one, with a fallback to the legacy name.

Refactored getOAuthTokenMacOS into smaller focused functions:
- findKeychainServiceName: discovers the correct service name
- readKeychainContent: reads content from a given service
- extractTokenFromKeychainContent: parses token from content
When the macOS Keychain entry doesn't exist (e.g., after re-authenticating
in tmux/byobu), fall back to checking credential files (~/.claude/.credentials.json,
etc.) matching the existing Linux behavior.

Based on tylergraydev#15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add two new block segment features:
- timeDisplay option: show "remaining" (3h20m) or "absolute" (2:30pm) reset time
- Sparkline history: visual usage trend (▁▂▃▄▅▆▇█) stored in ~/.claude/limitline-history.json

Based on tylergraydev#9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tylergraydev added a commit that referenced this pull request Feb 23, 2026
Claude Code now stores credentials under a hash-suffixed keychain
service name (e.g. "Claude Code-credentials-697375ae") instead of
the previous "Claude Code-credentials". This caused 401 Unauthorized
errors when fetching usage data.

Dynamically discovers the correct keychain service name by searching
for all matching entries and preferring the most specific (longest)
match, with a fallback to the legacy name.

Based on the approach from #14 by @xicv.
@tylergraydev

Copy link
Copy Markdown
Owner

Thanks for the contribution @xicv! The Keychain hash-suffix discovery was a great find.

We've extracted just that fix into #16 (now merged), which includes your findKeychainServiceName() approach and the extractTokenFromKeychainContent() refactor. We credited your work in the commit message.

We closed this PR because it bundled three separate concerns into one:

  1. The Keychain hash-suffix fix (novel — now in fix: support hash-suffixed macOS Keychain service name #16)
  2. Credential file fallback (already merged in Fix macOS OAuth: fall back to credential files when Keychain is missing #15)
  3. Sparkline + time toggle feature (already merged from Add sparkline history and reset time toggle #9)

Appreciate the effort — the core fix was solid!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants