fix(agents): existing agents pick up a later-connected key; stop advising an impossible login - #323
Open
stubbi wants to merge 2 commits into
Open
fix(agents): existing agents pick up a later-connected key; stop advising an impossible login#323stubbi wants to merge 2 commits into
stubbi wants to merge 2 commits into
Conversation
…ed key
Credential inheritance ran only while an agent was being created. That is the
wrong moment for the ordinary case: a company and its built-in agents exist
from signup, and the user connects a provider key afterwards. Nothing re-ran
inheritance, so those agents stayed credential-less permanently.
A hosted company hit the full consequence. Their Claude token was active and
company-scoped, but bound to the single agent they had made by hand. Both
built-in agents had no env binding at all, and the built-in Summarizer sat
paused on "Connect a model key to run this agent" while its configuration was
untouched factory default. From the user's side a stock agent simply could not
run, and nothing on screen explained why.
Two places now re-run the same donor rule over agents that already exist:
- the built-in ensure path, which every built-in agent goes through, so one
provisioned before any key existed picks the company credential up;
- after a credential lands on any agent via PATCH, so the rest of the
company (built-ins included) is wired at the moment of connecting rather
than whenever that agent is next ensured.
The rule is unchanged from create time: same CEO-preferred donor, same merge,
and an agent that already carries its own credential is never touched. That
makes a second pass a no-op, so repeated connects cannot rewrite anything, and
a deliberate per-agent key always wins. The decision is a pure function taking
the agent rows, so the behaviour is covered without a database.
Resuming stays a user action. A paused agent's reason already says to resume,
and auto-resuming an agent that spends the user's provider quota is not ours
to decide.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…not run When the Claude CLI reports "not logged in" it advises an interactive `/login`, and the adapter surfaced that line verbatim as the run error. A Paperclip run can never perform it: the run is headless, and on a managed sandbox the pod is destroyed with the lease. A paying hosted user was left chasing a command that does not exist for them, with no hint that the real fix is to reconnect the credential. The sibling case was already handled: a credential that is present but rejected resolves to CLAUDE_INVALID_CREDENTIAL_MESSAGE rather than the provider's raw 401. This gives "not logged in" the same treatment, leading with the remedy that works here and keeping host login as the self-hosted footnote, which is the shape codex-local already uses for its managed-home credential error. The trigger in the wild was a Claude OAuth token revoked at Anthropic. It is worth naming that case in the message: the token is well-formed and stored intact, so nothing about it looks wrong to the user, and "mint a fresh one" is the only thing that helps. Classification is unchanged (still claude_auth_required, still covered by the permanent-auth pause) and the raw CLI text is still kept in resultJson. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Both fixes come out of one hosted company's report: since subscribing, not a
single agent run had ever succeeded, including one from the built-in
Summarizer with untouched factory configuration.
The sandbox fault behind their 8 failed runs was #322. Chasing the rest of
their account surfaced two further faults, one of which affects every signup.
1. An agent that already exists never picks up a later-connected key
inheritCompanyCredentialEnvran only on the create path. The ordinary orderof events is the opposite: the company and its built-in agents exist from
signup, the user connects a key afterwards, and nothing re-runs inheritance.
Ground truth for the reporting company:
env.CLAUDE_CODE_OAUTH_TOKENTheir company secret was active and company-scoped the whole time. A stock
built-in agent could not run and nothing explained why.
Now re-run on the built-in ensure path and after a credential lands via PATCH.
Same donor rule as create time, agents with their own credential untouched,
second pass is a no-op. The decision is a pure function over the agent rows,
so it is tested without a database.
2. "not logged in" advised an interactive
/loginThe adapter surfaced the CLI's line verbatim. A Paperclip run cannot perform
an interactive login: it is headless, and on a managed sandbox the pod dies
with the lease. The rejected-credential sibling case already got a written
remedy; this gives the same to "not logged in", in the shape codex-local
already uses.
The live trigger: the reporting user's Claude OAuth token is revoked at
Anthropic. Decrypted in-pod it is well-formed (len 108,
sk-ant-oat01-prefix, no whitespace, stored fingerprint matches), so nothing looks wrong to
them;
api.anthropic.comanswers401 OAuth access token has been revoked.Minting a fresh token is the only thing that helps, so the message says so.
Classification is unchanged and the raw CLI text stays in
resultJson.🤖 Generated with Claude Code