fix(auth): include legacy OAuth sidecars in secrets-runtime store load

The embedded agent runner — Telegram replies, cron invocations, any
sub-agent dispatch — calls into the secrets runtime to resolve provider
auth. That path goes through `loadAuthProfileStoreForSecretsRuntime`,
which hardcoded `resolveLegacyOAuthSidecars: false`. As a result, OAuth
profiles whose credential material lives in the legacy sidecar layout
(`oauthRef.source: "openclaw-credentials"`, hash-named files under
`<state>/credentials/auth-profiles/<id>.json`) were loaded without their
access/refresh tokens, and `resolveApiKeyForProfile()` fell through to
the "No API key found for provider" error.

The OAuth-manager-internal helper added in #83312 already sets this to
`true`, but the secrets-runtime path is a parallel entry point: when the
embedded agent resolves provider auth for a model turn, it loads the
store through this helper, *before* the OAuth manager's own reload would
have a chance to compensate. Direct CLI inference is unaffected because
it routes through a different store-load path that still sees the
material.

Repro (against v2026.5.19 stock):
  1. Have an `openai-codex:default` profile with type=oauth and
     `oauthRef.source = "openclaw-credentials"` (typical for users who
     onboarded before the sidecar runtime was removed in #82777).
  2. Send a Telegram message to the bot, or wait for any cron with an
     embedded payload to fire.
  3. Gateway logs:
       [diagnostic] lane task error: ... error="Error: No API key found
       for provider \"openai-codex\". Auth store: .../auth-profiles.json
       ... Configure auth for this agent (openclaw agents add <id>) or
       copy only portable static auth profiles from the main agentDir."
  4. Meanwhile, `openclaw infer model run --model openai/gpt-5.5
     --prompt "say OK"` returns a normal completion using the same
     OAuth profile.

Fix: flip the hardcoded default in
`loadAuthProfileStoreForSecretsRuntime` from `false` to `true`, matching
the OAuth-manager helper's choice. Sidecar resolution is read-only and
already gated by per-process feature gates downstream, so this is safe
to enable unconditionally for the secrets-runtime load.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Will (via Claude Code)
2026-05-20 15:29:23 -07:00
parent fefdf52d36
commit 85f36e8d2b

View File

@@ -590,7 +590,17 @@ export function loadAuthProfileStoreForSecretsRuntime(agentDir?: string): AuthPr
return loadAuthProfileStoreForRuntime(agentDir, {
readOnly: true,
allowKeychainPrompt: false,
resolveLegacyOAuthSidecars: false,
// L4 PATCH (lane-pump branch): include legacy OAuth sidecar material when
// the runtime is resolving secrets for an agent turn. Without this, embedded
// agent runs (Telegram replies, cron invocations) cannot reach the access
// token for openai-codex profiles whose `oauthRef.source` is
// "openclaw-credentials", and resolveApiKeyForProfile() falls through to
// "No API key found". The OAuth-manager-internal refresh helper added in
// upstream #83312 already sets this to true; this default was inadvertently
// left at `false` after the sidecar runtime removal in #82777, breaking
// the embedded-agent OAuth resolution path while leaving the direct CLI
// inference path unaffected. See UPSTREAM_ISSUE_DRAFT.md in local-patches.
resolveLegacyOAuthSidecars: true,
});
}