openclaw - 💡(How to fix) Fix openai-codex provider auth: paste-token produces wrong shape; missing API-key mode CLI

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…

openclaw models auth paste-token --provider openai-codex writes an auth profile with a shape (type:"token", token field) that does not work with the codex harness. The harness routes token-mode profiles through set_external_auth RPC and treats the value as an OAuth ID token (JWT), so pasting an OpenAI API key (sk-…) yields failed to set external auth: invalid ID token format at request time.

The only shape that actually works for an API-key auth flow is:

{
  "type": "api_key",
  "provider": "openai-codex",
  "key": "sk-…"
}

…with a matching openclaw.json entry of mode:"api_key". There appears to be no CLI command that produces this combination — paste-token always writes type:"token", and login requires interactive TTY OAuth.

Error Message

Set OPENAI_API_KEY env var to a valid sk-proj-... key

Try the CLI:

printenv OPENAI_API_KEY | openclaw models auth --agent main paste-token --provider openai-codex

Result: writes type:"token" profile, but request-time fails with:

CodexAppServerRpcError: failed to set external auth: invalid ID token format

Root Cause

ShapeOutcomeRoot cause
type:"api_key", provider:"openai-codex", api_key:KMissing API key for provider "openai-codex"oauth-BiX6jZGO.js:718 resolveApiKeyForProfile reads cred.key, not cred.api_key
type:"token", provider:"openai-codex", token:K (what paste-token produces)invalid ID token formatcodex harness sends value via set_external_auth expecting a JWT
type:"api_key", provider:"openai", api_key:KMissing API key for provider "openai-codex"listProfilesForProvider uses exact resolveProviderIdForAuth match; openai-typed profile is not surfaced to the codex provider lookup
type:"api_key", provider:"openai-codex", key:Kworkscorrect shape — matches resolveApiKeyForProfile api_key branch

Fix Action

Fix / Workaround

Anyone trying to run OpenClaw with a bring-your-own OpenAI API key on a headless host (Zeabur, Docker, CI) ends up with this issue. OAuth login isn't an option there. The current workaround requires reading minified bundles to discover the correct shape.

Workaround for current users

Code Example

{
  "type": "api_key",
  "provider": "openai-codex",
  "key": "sk-…"
}

---

# Set OPENAI_API_KEY env var to a valid sk-proj-... key

# Try the CLI:
printenv OPENAI_API_KEY | openclaw models auth --agent main paste-token --provider openai-codex
# Result: writes type:"token" profile, but request-time fails with:
#   CodexAppServerRpcError: failed to set external auth: invalid ID token format

---

python3 << 'PY'
import json, os
AP = "/path/to/agents/main/agent/auth-profiles.json"
CP = os.path.expanduser("~/.openclaw/openclaw.json")
K = os.environ["OPENAI_API_KEY"]
PID = "openai-codex:manual"

ap = json.load(open(AP))
ap["profiles"][PID] = {"type": "api_key", "provider": "openai-codex", "key": K}
json.dump(ap, open(AP, "w"), indent=2)

cp = json.load(open(CP))
a = cp.setdefault("auth", {})
a.setdefault("profiles", {})[PID] = {"provider": "openai-codex", "mode": "api_key"}
a.setdefault("order", {})["openai-codex"] = [PID]
json.dump(cp, open(CP, "w"), indent=2)
PY
openclaw gateway restart
RAW_BUFFERClick to expand / collapse

Summary

openclaw models auth paste-token --provider openai-codex writes an auth profile with a shape (type:"token", token field) that does not work with the codex harness. The harness routes token-mode profiles through set_external_auth RPC and treats the value as an OAuth ID token (JWT), so pasting an OpenAI API key (sk-…) yields failed to set external auth: invalid ID token format at request time.

The only shape that actually works for an API-key auth flow is:

{
  "type": "api_key",
  "provider": "openai-codex",
  "key": "sk-…"
}

…with a matching openclaw.json entry of mode:"api_key". There appears to be no CLI command that produces this combination — paste-token always writes type:"token", and login requires interactive TTY OAuth.

Environment

  • OpenClaw version: 2026.5.19 (image ghcr.io/openclaw/openclaw:2026.5.19)
  • Deployment: Zeabur, single-pod headless (no browser available for OAuth)
  • Use case: bring-your-own OpenAI API key for openai/gpt-5.5 agent model

Reproduction

# Set OPENAI_API_KEY env var to a valid sk-proj-... key

# Try the CLI:
printenv OPENAI_API_KEY | openclaw models auth --agent main paste-token --provider openai-codex
# Result: writes type:"token" profile, but request-time fails with:
#   CodexAppServerRpcError: failed to set external auth: invalid ID token format

What I tried (and why each failed)

ShapeOutcomeRoot cause
type:"api_key", provider:"openai-codex", api_key:KMissing API key for provider "openai-codex"oauth-BiX6jZGO.js:718 resolveApiKeyForProfile reads cred.key, not cred.api_key
type:"token", provider:"openai-codex", token:K (what paste-token produces)invalid ID token formatcodex harness sends value via set_external_auth expecting a JWT
type:"api_key", provider:"openai", api_key:KMissing API key for provider "openai-codex"listProfilesForProvider uses exact resolveProviderIdForAuth match; openai-typed profile is not surfaced to the codex provider lookup
type:"api_key", provider:"openai-codex", key:Kworkscorrect shape — matches resolveApiKeyForProfile api_key branch

The harnessCanForwardProfile check in auth-WUYjZATL.js does allow forwarding an openai-typed api_key profile to the codex harness, but only after listProfilesForProvider("openai-codex") has already returned at least one candidate, which it never does for an openai-typed profile.

Proposed fixes

Pick one or both:

  1. Make paste-token --provider openai-codex write the correct shape. When provider === "openai-codex" (and possibly other CLI-backed providers), default to type:"api_key" with key field, not type:"token". The current behavior produces an unrecoverable profile that has to be hand-edited.

  2. Add openclaw models auth paste-api-key --provider <p> as an explicit non-interactive command for API-key mode, distinct from the existing paste-token (which is OAuth-token oriented). This avoids any back-compat concern with paste-token.

  3. Better diagnostic. When resolveApiKeyForProfile sees cred.api_key but the schema requires cred.key, emit a clear "wrong field name" error instead of falling through to "No API key found" — that error message points at the auth store path and suggests openclaw agents add, neither of which is the actual fix.

Severity / blast radius

Anyone trying to run OpenClaw with a bring-your-own OpenAI API key on a headless host (Zeabur, Docker, CI) ends up with this issue. OAuth login isn't an option there. The current workaround requires reading minified bundles to discover the correct shape.

Workaround for current users

python3 << 'PY'
import json, os
AP = "/path/to/agents/main/agent/auth-profiles.json"
CP = os.path.expanduser("~/.openclaw/openclaw.json")
K = os.environ["OPENAI_API_KEY"]
PID = "openai-codex:manual"

ap = json.load(open(AP))
ap["profiles"][PID] = {"type": "api_key", "provider": "openai-codex", "key": K}
json.dump(ap, open(AP, "w"), indent=2)

cp = json.load(open(CP))
a = cp.setdefault("auth", {})
a.setdefault("profiles", {})[PID] = {"provider": "openai-codex", "mode": "api_key"}
a.setdefault("order", {})["openai-codex"] = [PID]
json.dump(cp, open(CP, "w"), indent=2)
PY
openclaw gateway restart

Related files in source

  • src/agents/auth-profiles/oauth.ts (compiled oauth-BiX6jZGO.js:718) — resolveApiKeyForProfile
  • src/agents/runtime-plan/auth.ts (compiled auth-WUYjZATL.js) — codex harness forwarding rules
  • src/commands/models/auth-paste-token.ts (compiled auth-BAKjt1sr.js:282) — modelsAuthPasteTokenCommand
  • src/agents/auth-profiles/profile-list.ts (compiled profile-list-U8pxO857.js) — listProfilesForProvider

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