[BUG] OAuth tokens expire silently, breaking unattended automation (LaunchAgent/cron)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code authenticates via OAuth tokens that expire. When running claude in an unattended/headless context (LaunchAgent, cron job, CI), there's no way to detect or recover from expiry — the process just fails with a 401 and the scheduled job is silently skipped.
Reproduction:
- Log in via claude auth login
- Set up a LaunchAgent or cron job that runs claude on a schedule
- Wait for the OAuth token to expire
- Observe: the scheduled job fails silently with 401 OAuth token has expired
Impact:
The only workaround is to use ANTHROPIC_API_KEY instead of OAuth. But API key usage is billed at pay-per token rates — meaning users on Max subscriptions are forced to pay twice to use a basic automation pattern that their subscription should cover.
What Should Happen?
- Tokens should be automatically refreshed when a refresh token is available
- Headless/daemon token flows should produce longer-lived or non-expiring credentials
- At minimum, a clear error + notification path so the failure isn't silent
Error Messages/Logs
Failed to authenticate. API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired.
Please obtain a new token or refresh your existing token."},"request_id":"req_011CZPvHgEuvUB7be9op9hJ2"}
Steps to Reproduce
Run an automation that uses claude on a headless machine
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
N/A - this just started happening in the last week or two
Claude Code Version
2.1.83 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗