Skip to content

An ambient ANTHROPIC_API_KEY out-ranks the operator's login for the nested summarizer, and an exhausted one fails every background save silently #703

Description

@fdaviddpt

Reported by @Mega-Therion in #693, with the trace that identified it. Filing the symptom so the fix has an issue to close, per that PR's review.

What happens

_child_env() in pipeline/haiku.py passes the host environment through to the nested claude -p the background summarizer spawns, stripping only the parent-session markers. ANTHROPIC_API_KEY goes through with it.

The Claude CLI resolves credentials in a fixed order, and that key out-ranks a claude.ai login. So on a host where the operator has both — a login they chose, and an API key set in their shell for some unrelated tool — every nested summarizer call authenticates as the key, not as the login.

When that key's balance is exhausted or rate-limited, every background save fails:

[haiku] call exited 1; ...
[haiku] ERROR: call-haiku error: claude exited 1: Credit balance is too low | ⚠ claude.ai connectors are disabled because ANTHROPIC_API_KEY or another auth source is set and takes precedence over your claude.ai login · Unset it to load your organization's connectors

Observed 12 times across several days on one installation.

Why it is hard to see

The operator's own interactive sessions keep working — they run off the login, which is not out-ranked in that context. Only the nested child is affected. In hook-errors.log the whole thing reads as save-session.sh --force exited 1, with the real cause going to the daily narrative log and nowhere else (#694). Nothing at any layer names the variable.

Why the obvious fix is not the whole fix

Stripping ANTHROPIC_API_KEY unconditionally moves the outage rather than removing it: for an operator whose only credential is that key — a normal, documented way to authenticate the CLI, with no claude.ai login and no setup-token — a strip leaves the child unauthenticated and every background save fails, silently, in exactly the same shape.

So the fix has to distinguish the two populations: strip the ambient key when another credential is actually available, keep it when it is the only one there is. What "available" can mean is itself limited — a claude.ai login stored in the macOS Keychain is not visible to this process the way ~/.claude/.credentials.json is — so whatever automatic rule ships needs an explicit operator override alongside it, and the failure needs to name the variable when it does bite.

Acceptance

  • An ambient ANTHROPIC_API_KEY no longer reaches the nested CLI when another credential is available.
  • It still reaches it when it is the only credential present.
  • An operator can force either behaviour when the automatic rule cannot see their login.
  • A failure that this variable plausibly caused says so, in the place the operator is already looking.

[AI-generated]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglane-capturein-session hooks and the summarizer — post-tool, prompt, session-start/end, haiku.py, prompts/priority:mediumRecurring cost; compounds if unfixed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions