openclaw - 💡(How to fix) Fix Legacy Codex OAuth sidecars stored only in macOS Keychain still require doctor for embedded runtime path

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

#85074 (and the original #84752) restore runtime auto-migration of legacy oauthRef-backed openai-codex profiles for the embedded runner — but only when the sidecar seed lives in OPENCLAW_AUTH_PROFILE_SECRET_KEY or in a seed file under ~/.openclaw/oauth/.... Users whose legacy seed lives only in macOS Keychain (older onboarding before the file-based sidecar layout) are not self-healed by that PR and still need a one-time openclaw doctor --fix.

This issue tracks closing that remaining gap.

Error Message

  • Headless invocations that detect a Keychain-only profile fail with a clear actionable error directing the user to run from a terminal or run doctor.

Root Cause

#85074 (and the original #84752) restore runtime auto-migration of legacy oauthRef-backed openai-codex profiles for the embedded runner — but only when the sidecar seed lives in OPENCLAW_AUTH_PROFILE_SECRET_KEY or in a seed file under ~/.openclaw/oauth/.... Users whose legacy seed lives only in macOS Keychain (older onboarding before the file-based sidecar layout) are not self-healed by that PR and still need a one-time openclaw doctor --fix.

This issue tracks closing that remaining gap.

Fix Action

Fix / Workaround

The embedded runtime path runs with allowKeychainPrompt: false (src/agents/auth-profiles/legacy-oauth-sidecar.ts:233-240) by design — embedded turns happen in Telegram replies, cron-triggered runs, sub-agent dispatch, and other contexts where popping an unexpected macOS Keychain prompt would be confusing or impossible. Simply flipping that flag to true is not acceptable: it would surface Keychain prompts at random times when no user is looking at the terminal.

B. Auto-trigger the doctor migration on first interactive openclaw <anything> invocation after a detected legacy profile. Cleaner mental model — the migration stays doctor's responsibility, but it's triggered automatically once instead of requiring the user to know about it. Probably ~100-200 LOC in the command dispatch entry point + reuse of existing maybeRepairLegacyOAuthSidecarProfiles.

  • macOS Keychain-only legacy sidecar users self-heal on first interactive openclaw invocation after upgrade (whichever approach is chosen).
  • No Keychain prompts fire in headless contexts (cron, systemd, Telegram polling, embedded sub-agent dispatch).
  • Headless invocations that detect a Keychain-only profile fail with a clear actionable error directing the user to run from a terminal or run doctor.
  • Regression test covers both "interactive: migrate" and "headless: refuse cleanly" paths.
RAW_BUFFERClick to expand / collapse

Summary

#85074 (and the original #84752) restore runtime auto-migration of legacy oauthRef-backed openai-codex profiles for the embedded runner — but only when the sidecar seed lives in OPENCLAW_AUTH_PROFILE_SECRET_KEY or in a seed file under ~/.openclaw/oauth/.... Users whose legacy seed lives only in macOS Keychain (older onboarding before the file-based sidecar layout) are not self-healed by that PR and still need a one-time openclaw doctor --fix.

This issue tracks closing that remaining gap.

Why it's not in #85074

The embedded runtime path runs with allowKeychainPrompt: false (src/agents/auth-profiles/legacy-oauth-sidecar.ts:233-240) by design — embedded turns happen in Telegram replies, cron-triggered runs, sub-agent dispatch, and other contexts where popping an unexpected macOS Keychain prompt would be confusing or impossible. Simply flipping that flag to true is not acceptable: it would surface Keychain prompts at random times when no user is looking at the terminal.

So the runtime self-heal works for file/env-seed users (the modal case) but not Keychain-only users, who are documented as still needing doctor (docs/gateway/doctor.md section 5).

Affected users

Anyone who:

  • Onboarded openai-codex OAuth on a macOS host before the file-based sidecar layout was introduced, AND
  • Did not set OPENCLAW_AUTH_PROFILE_SECRET_KEY or write a seed file, AND
  • Upgraded with manual npm/pnpm/bun (skipping the openclaw update → doctor flow).

Same surface as #84893 / #85074, narrower bucket.

Two viable approaches

A. Prompt-once-and-cache in the embedded runtime path. Detect Keychain-backed legacy sidecars on first embedded-runtime store load. If the calling context is genuinely interactive (TTY attached, not cron/systemd/Telegram-bot-reply), prompt the user once to unlock the Keychain entry. On approval, read the seed, migrate all sidecar profiles inline via the existing saveAuthProfileStore path, and never need to prompt again. If the context is headless, fail gracefully with a clear message directing the user to run openclaw doctor from a terminal.

B. Auto-trigger the doctor migration on first interactive openclaw <anything> invocation after a detected legacy profile. Cleaner mental model — the migration stays doctor's responsibility, but it's triggered automatically once instead of requiring the user to know about it. Probably ~100-200 LOC in the command dispatch entry point + reuse of existing maybeRepairLegacyOAuthSidecarProfiles.

B is architecturally cleaner — it avoids spreading "when is it safe to prompt for Keychain access?" logic into the embedded runtime. A is more surgical but harder to get right.

Acceptance criteria

  • macOS Keychain-only legacy sidecar users self-heal on first interactive openclaw invocation after upgrade (whichever approach is chosen).
  • No Keychain prompts fire in headless contexts (cron, systemd, Telegram polling, embedded sub-agent dispatch).
  • Headless invocations that detect a Keychain-only profile fail with a clear actionable error directing the user to run from a terminal or run doctor.
  • Regression test covers both "interactive: migrate" and "headless: refuse cleanly" paths.

Related

  • #85074 (closes the file/env-seed bucket; this issue is the remaining Keychain-only bucket).
  • #84752 (original PR; auth half cherry-picked into #85074).
  • #84893 (P1 upgrade regression that surfaced the broader bug; same user audience).
  • #83312 (introduced the runtime auto-migration the runtime path now correctly reaches for file/env seeds).
  • docs/gateway/doctor.md section 5 documents Keychain-only as doctor-required today.

Out of scope

  • Removing the legacy sidecar code paths entirely. That's a separate cleanup tracked elsewhere and should wait until all legacy users have migrated.
  • Changes to openclaw doctor --fix behavior itself; the migration path it runs is already correct.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING