Problem
When OAuth token expires and API returns 401, the refresh retry is silently skipped because refreshToken is null.
Root cause: config.json has apiKey (OAuth token) but no refreshToken field. The Keychain credential loading should populate refreshToken, but if it fails for any reason (first boot, Keychain locked, macOS permission dialog), refreshToken stays null.
The 401 retry condition at AnthropicClient.java:164:
if (statusCode == 401 && isOAuth && refreshToken != null) {
silently falls through to the error path without any log message, making the failure invisible.
Impact
- Cron jobs fail with "Invalid API key" after token expiry
- No log message explains why refresh was skipped
- User has to restart daemon to pick up a new token
Fix
- Log a warning when 401 is received but
refreshToken is null
- Attempt to re-read refresh token from Keychain on 401 (it may have been updated by Claude CLI)
- Add
refreshToken field to config.json documentation
Related
Problem
When OAuth token expires and API returns 401, the refresh retry is silently skipped because
refreshTokenisnull.Root cause:
config.jsonhasapiKey(OAuth token) but norefreshTokenfield. The Keychain credential loading should populaterefreshToken, but if it fails for any reason (first boot, Keychain locked, macOS permission dialog),refreshTokenstays null.The 401 retry condition at
AnthropicClient.java:164:silently falls through to the error path without any log message, making the failure invisible.
Impact
Fix
refreshTokenis nullrefreshTokenfield to config.json documentationRelated