Fix expired OAuth token and keychain lookup issues#3
Fix expired OAuth token and keychain lookup issues#3inspiretelapps wants to merge 1 commit intorobinebers:mainfrom
Conversation
The script was silently failing to show API usage limits because: 1. On systems with multiple "Claude Code-credentials" keychain entries (e.g. an old "root" entry and a current user entry), macOS returned the stale one. Now looks up by current username first. 2. OAuth tokens expire after 8 hours but the script had no refresh logic. Added automatic token refresh via platform.claude.com with a 1-hour token cache to avoid unnecessary refresh calls. 3. The API response format changed — seven_day_opus is now null for non-Opus users, with seven_day_sonnet returned instead. The script now dynamically detects which model-specific limit is available. 4. The color_pct function threw "integer expression expected" errors when receiving empty or non-numeric values from failed API calls. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix OAuth token expiry and keychain lookup in
|
| new_token=$(echo "$refresh_result" | jq -r '.access_token // empty' 2>/dev/null) | ||
| if [ -n "$new_token" ]; then | ||
| # Cache the refreshed token | ||
| echo "$refresh_result" > "$TOKEN_CACHE_FILE" |
There was a problem hiding this comment.
🔴 Critical
statusline-command.sh:59
OAuth tokens are written to /tmp/claude-oauth-token-cache.json with default (world-readable) permissions, allowing any local user to steal credentials. Consider restricting permissions with chmod 600 after writing or using a user-specific directory like ~/.cache/.
- echo "$refresh_result" > "$TOKEN_CACHE_FILE"
+ echo "$refresh_result" > "$TOKEN_CACHE_FILE"
+ chmod 600 "$TOKEN_CACHE_FILE"🚀 Want me to fix this? Reply ex: "fix it for me".
Greptile OverviewGreptile SummaryFixes OAuth token expiration by adding automatic refresh logic with 1-hour caching, resolves keychain ambiguity by filtering on current username, and adapts to API changes where model limits now return Key improvements:
Minor portability notes:
Confidence Score: 4/5
Important Files Changed
|
| get_access_token() { | ||
| # Check token cache first (refreshed tokens are cached here) | ||
| if [ -f "$TOKEN_CACHE_FILE" ]; then | ||
| token_cache_age=$(($(date +%s) - $(stat -f %m "$TOKEN_CACHE_FILE" 2>/dev/null || echo 0))) |
There was a problem hiding this comment.
stat -f is BSD/macOS-only; add Linux compatibility with stat -c
Prompt To Fix With AI
This is a comment left during a code review.
Path: statusline-command.sh
Line: 21:21
Comment:
`stat -f` is BSD/macOS-only; add Linux compatibility with `stat -c`
How can I resolve this? If you propose a fix, please make it concise.| security delete-generic-password -s "Claude Code-credentials" -a "$acct" >/dev/null 2>&1 | ||
| security add-generic-password -s "Claude Code-credentials" -a "$acct" -w "$updated_creds" 2>/dev/null |
There was a problem hiding this comment.
Race condition: keychain delete/add isn't atomic; concurrent statusline calls could corrupt credentials
Prompt To Fix With AI
This is a comment left during a code review.
Path: statusline-command.sh
Line: 68:69
Comment:
Race condition: keychain delete/add isn't atomic; concurrent statusline calls could corrupt credentials
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: statusline-command.sh
Line: 90:90
Comment:
`stat -f` is BSD/macOS-only; add Linux compatibility with `stat -c`
How can I resolve this? If you propose a fix, please make it concise. |
There was a problem hiding this comment.
2 issues found across 1 file
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="statusline-command.sh">
<violation number="1" location="statusline-command.sh:59">
P1: OAuth tokens written to `/tmp` are world-readable by default. This exposes the access token to other users on multi-user systems. Set restrictive permissions when writing sensitive credentials.</violation>
<violation number="2" location="statusline-command.sh:166">
P2: When `pct` is empty, this outputs just `%` with no number. The empty check should substitute a default value to display `0%` instead.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| new_token=$(echo "$refresh_result" | jq -r '.access_token // empty' 2>/dev/null) | ||
| if [ -n "$new_token" ]; then | ||
| # Cache the refreshed token | ||
| echo "$refresh_result" > "$TOKEN_CACHE_FILE" |
There was a problem hiding this comment.
P1: OAuth tokens written to /tmp are world-readable by default. This exposes the access token to other users on multi-user systems. Set restrictive permissions when writing sensitive credentials.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At statusline-command.sh, line 59:
<comment>OAuth tokens written to `/tmp` are world-readable by default. This exposes the access token to other users on multi-user systems. Set restrictive permissions when writing sensitive credentials.</comment>
<file context>
@@ -12,9 +12,70 @@ model=$(echo "$input" | jq -r '.model.display_name')
+ new_token=$(echo "$refresh_result" | jq -r '.access_token // empty' 2>/dev/null)
+ if [ -n "$new_token" ]; then
+ # Cache the refreshed token
+ echo "$refresh_result" > "$TOKEN_CACHE_FILE"
+
+ # Update Keychain with new credentials
</file context>
| echo "$refresh_result" > "$TOKEN_CACHE_FILE" | |
| echo "$refresh_result" > "$TOKEN_CACHE_FILE" | |
| chmod 600 "$TOKEN_CACHE_FILE" |
| local pct=$1 | ||
| if [ "$pct" -ge 90 ]; then | ||
| if [ -z "$pct" ] || [ "$pct" = "0" ]; then | ||
| echo "\033[32m${pct}%\033[0m" # green |
There was a problem hiding this comment.
P2: When pct is empty, this outputs just % with no number. The empty check should substitute a default value to display 0% instead.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At statusline-command.sh, line 166:
<comment>When `pct` is empty, this outputs just `%` with no number. The empty check should substitute a default value to display `0%` instead.</comment>
<file context>
@@ -91,9 +162,11 @@ fi
local pct=$1
- if [ "$pct" -ge 90 ]; then
+ if [ -z "$pct" ] || [ "$pct" = "0" ]; then
+ echo "\033[32m${pct}%\033[0m" # green
+ elif [ "$pct" -ge 90 ] 2>/dev/null; then
echo "\033[31m${pct}%\033[0m" # red
</file context>
| echo "\033[32m${pct}%\033[0m" # green | |
| echo "\033[32m${pct:-0}%\033[0m" # green |
|
Thank you, I think it might be a better idea to turn this into a Claude Skill now that they're so powerful to keep this dynamic! Will consider and merge your changes then. 🙏 |
Summary
The statusline script silently fails to show API usage limits when OAuth tokens expire. This PR fixes three root causes:
Claude Code-credentialskeychain entries (e.g. a stalerootentry alongside the current user entry),security find-generic-passwordreturns the wrong one. Now resolves by current username (whoami) first, with fallback.platform.claude.com/v1/oauth/tokenwith a 1-hour file-based token cache to avoid unnecessary refresh calls on every statusline update.seven_day_opusis nownullfor non-Opus users;seven_day_sonnetis returned instead. The script now dynamically picks whichever model-specific limit is available and labels it accordingly.color_pctthrewinteger expression expectedwhen the API call failed and returned empty values. Added guards for empty/non-numeric inputs.Test plan
🤖 Generated with Claude Code
Summary by cubic
Fixes silent failures in the statusline by refreshing expired OAuth tokens, resolving keychain lookup ambiguity, and adapting to the new API fields. Limits now display reliably with correct model labels and no integer errors.
Written for commit e6851d9. Summary will update on new commits.