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`

Open 💬 0 comments Opened Jul 16, 2026 by XTCNigel

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

  1. claude setup-token → complete browser OAuth → save the token (verify full length: 108 chars, sk-ant-oat01- prefix).
  2. Ensure no other credentials: remove/rename ~/.claude/.credentials.json; ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN unset; no apiKeyHelper.
  3. Launch headless in tmux with the token exported into the session env: claude --channels plugin:imessage@claude-plugins-official.
  4. Send a real inbound message through the channel. (On our first deploy this worked normally for 1.5+ hours.)
  5. 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.
  6. Send an inbound message → "API Error: 401 Invalid authentication credentials".
  7. 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.

View original on GitHub ↗