Setup-token (CLAUDE_CODE_OAUTH_TOKEN) fails with 401 in long-running `claude --channels` process while the same token works in one-shot `claude -p`
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?
A long-lived token from claude setup-token (verified byte-exact: 108 chars, sk-ant-oat01- prefix) authenticates one-shot claude -p runs reliably, but the long-running claude --channels process fails requests with 401 "Invalid authentication credentials" under the same environment.
Timeline: on first deployment the channels process worked normally on token-only auth for 1.5+ hours (real inbound messages answered). After a scheduled overnight restart with an identical, verified environment (token present in the process env, no stored credentials), it never completed a turn again — first inbound the next morning got "API Error: 401 Invalid authentication credentials / Please run /login". A fresh manual restart also 401'd on its very first inbound, ruling out time-based staleness at that point. Throughout, one-shot claude -p "test" with the same token (and stored credentials absent, fresh HOME) kept succeeding, reproducibly. Only recovery: interactive /login.
Additional observation from diagnosis (credential precedence, established empirically): when ~/.claude/.credentials.json exists alongside an invalid CLAUDE_CODE_OAUTH_TOKEN, requests silently succeed via the stored credentials with no warning that the env token was bad (masked the problem for a day; related to #16238). With no credentials file, a non-empty env token is used (an invalid one correctly 401s); with an empty/absent env var, macOS Keychain credentials are used.
Possibly related: #65320 (closed — setup-token rejected even in one-shot claude -p; distinct: here one-shot succeeds and only --channels fails), #54738 (setup-token output line-wrap breaking copy-paste — independently hit during deployment), #8938, #5143, #37512, #54443; #28827 and #50743 are closed as duplicates of an unnamed canonical issue. None describes the one-shot-works / channels-fails split.
Question: is claude setup-token supported for long-running --channels sessions? If yes, this looks like the long-running session's auth/exchange path failing where one-shot invocations succeed.
What Should Happen?
The setup-token should authenticate the long-running claude --channels process the same way it authenticates one-shot claude -p invocations — running headless/unattended on a subscription is the documented purpose of claude setup-token.
Error Messages/Logs
API Error: 401 Invalid authentication credentials
Please run /login
(While at the same moment, on the same machine: CLAUDE_CODE_OAUTH_TOKEN=<same token> claude -p "test" → succeeds.)
Steps to Reproduce
claude setup-token→ complete browser OAuth → save the token (verify full length: 108 chars, sk-ant-oat01- prefix).- Ensure no other credentials: remove/rename ~/.claude/.credentials.json; ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN unset; no apiKeyHelper.
- Launch headless in tmux with the token exported into the session env:
claude --channels plugin:imessage@claude-plugins-official. - Send a real inbound message through the channel. (On our first deploy this worked normally for 1.5+ hours.)
- Restart the process with the identical environment (we used our scheduled restart script; a manual restart reproduces it too). Verify the token is present in the new process env.
- Send an inbound message → "API Error: 401 Invalid authentication credentials".
- In parallel:
CLAUDE_CODE_OAUTH_TOKEN=<same token> claude -p "test"in a fresh HOME with no stored credentials → succeeds every time.
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.211 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Interim workaround in use: interactive /login (which stores refreshable credentials) and re-logging in every ~4-5 days. Happy to provide exact timestamps, additional logs, or run diagnostics on request — this setup reproduces the issue reliably.