Skip to content

Subscription-mode Claude agents 401 (Invalid Bearer Token) when daemon env carries ANTHROPIC_AUTH_TOKEN #883

Description

@bucolicwalker-ops

Summary

Claude agents bound to an OAuth/subscription account fail with 401 Invalid Bearer Token whenever the daemon process was launched with ANTHROPIC_AUTH_TOKEN set in its environment (a common setup when other agents use an Anthropic-compatible proxy such as DashScope/Bailian).

Symptom

Failed to authenticate. API Error: 401 Invalid Bearer Token
{"type":"result","subtype":"success","is_error":true,"api_error_status":401, ... }

The invocation returns instantly with ~0 tokens — auth is rejected before any model call. Multiple cats sharing one OAuth account all fail identically.

Root cause

buildClaudeEnvOverrides() in packages/api/src/domains/cats/services/agents/providers/ClaudeAgentService.ts scrubs inherited credentials for subscription mode, but the list is incomplete:

} else if (mode === 'subscription') {
  // Subscription mode must not inherit shell-level Anthropic credentials.
  env.ANTHROPIC_API_KEY = null;
  env.ANTHROPIC_BASE_URL = null;   // resets to api.anthropic.com
  env.ANTHROPIC_MODEL = null;
  // ... ANTHROPIC_AUTH_TOKEN is NOT cleared
}

ANTHROPIC_AUTH_TOKEN is sent by the Claude CLI as Authorization: Bearer <token>. So when the daemon env has e.g.:

ANTHROPIC_BASE_URL=https://dashscope.aliyuncs.com/apps/anthropic
ANTHROPIC_AUTH_TOKEN=sk-d11…           # a DashScope/Bailian key

the subscription child gets ANTHROPIC_BASE_URL reset to api.anthropic.com but keeps the DashScope token, then sends that proxy token as a Bearer credential to Anthropic → 401 Invalid Bearer Token. It silently overrides the otherwise-valid native OAuth/Keychain login.

Note the error wording ("Invalid Bearer Token", not "invalid api key") confirms the ANTHROPIC_AUTH_TOKEN/Bearer path rather than ANTHROPIC_API_KEY/x-api-key.

Reproduction

  1. Configure one OAuth (my-claude-account) and one api_key proxy account (DashScope).
  2. Launch the daemon from a shell that exports ANTHROPIC_AUTH_TOKEN/ANTHROPIC_BASE_URL for the proxy.
  3. Message a cat bound to the OAuth account → 401 Invalid Bearer Token. The proxy-account cat works fine.

Test gap

The existing regression test F062: subscription profile clears inherited ANTHROPIC env vars only asserts ANTHROPIC_API_KEY/ANTHROPIC_BASE_URL are cleared — it never set or checked ANTHROPIC_AUTH_TOKEN, which is why this shipped.

Fix

Strip ANTHROPIC_AUTH_TOKEN alongside the other vars in subscription mode, and extend the F062 test to cover it. PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedMaintainer accepted: ready for implementation/mergebugSomething isn't workingtriagedMaintainer reviewed, replied, and made an initial triage decision

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions