openclaw - 💡(How to fix) Fix External CLI harnesses blocked by stale auth-profiles gate

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…

Plugin harnesses that delegate authentication to an external CLI (e.g., claude CLI via claude-tmux harness) can be blocked from spawning when OpenClaw's auth-profiles.json contains expired or disabled tokens for the associated provider — even though the harness itself never uses those stored tokens.

Root Cause

  1. OpenClaw checks auth-profiles.json for the anthropic provider
  2. If the stored token is expired or the profile has disabledReason: "billing" (from a past failure), the auth gate refuses to spawn
  3. The harness never gets a chance to run — even though it would succeed because the CLI has fresh tokens

Fix Action

Workaround

Sync CLI credentials to OpenClaw auth-profiles.json periodically and clear stale auth-state.json flags. Example: a systemd timer that reads ~/.claude/.credentials.json and writes to both main and agent auth-profiles every 4 hours.

Code Example

env_parts = ["env", "-u", "ANTHROPIC_API_KEY", "-u", "ANTHROPIC_AUTH_TOKEN", "-u", "ANTHROPIC_OAUTH_TOKEN"]

---

{
  "auth": {
    "mode": "external-cli",
    "ownsTransport": true,
    "requiresOpenClawAuthBootstrap": false,
    "forwardsAuthProfiles": false
  }
}
RAW_BUFFERClick to expand / collapse

External CLI harnesses blocked by stale OpenClaw auth-profiles gate

Summary

Plugin harnesses that delegate authentication to an external CLI (e.g., claude CLI via claude-tmux harness) can be blocked from spawning when OpenClaw's auth-profiles.json contains expired or disabled tokens for the associated provider — even though the harness itself never uses those stored tokens.

Environment

  • OpenClaw: v2026.5.x
  • Harness: claude-tmux (community plugin)
  • Provider: anthropic (Claude CLI OAuth)

Problem

Background

The claude-tmux harness launches the Claude CLI in a tmux session. The CLI handles its own authentication via ~/.claude/.credentials.json, which auto-refreshes OAuth tokens. The harness explicitly strips OpenClaw's auth environment variables:

env_parts = ["env", "-u", "ANTHROPIC_API_KEY", "-u", "ANTHROPIC_AUTH_TOKEN", "-u", "ANTHROPIC_OAUTH_TOKEN"]

The CLI's own auth is completely independent of OpenClaw's auth-profiles.json.

What goes wrong

OpenClaw's resolveHarnessAuthProvider() is hardcoded to only recognize the codex harness as needing special auth handling. For all other harnesses, it falls through to the canonical provider auth path:

  1. OpenClaw checks auth-profiles.json for the anthropic provider
  2. If the stored token is expired or the profile has disabledReason: "billing" (from a past failure), the auth gate refuses to spawn
  3. The harness never gets a chance to run — even though it would succeed because the CLI has fresh tokens

This caused an 18-day outage of the Claude agent because:

  • The stored anthropic:claude-cli token expired
  • A subsequent failure set disabledReason: "billing" in auth-state.json
  • Even after the CLI refreshed its own tokens, OpenClaw refused to spawn the harness

Current partial bypass

The installed core already has some structure for this:

  • pluginHarnessOwnsTransport is true for plugin harnesses (not pi)
  • pluginHarnessNeedsOpenClawAuthBootstrap is only true for openai-codex with openai-codex-responses
  • For harnesses that own transport and don't need bootstrap, OpenClaw uses an empty auth store

However, this bypass apparently doesn't fully prevent the auth gate from blocking. The disabledReason in auth-state.json still prevented spawns, suggesting the profile-selection or auth-state check runs before or alongside the transport-ownership check.

Proposed Fix

1. Harness auth metadata declaration

Allow harnesses to explicitly declare their auth requirements in registration metadata:

{
  "auth": {
    "mode": "external-cli",
    "ownsTransport": true,
    "requiresOpenClawAuthBootstrap": false,
    "forwardsAuthProfiles": false
  }
}

2. Make resolveHarnessAuthProvider() metadata-driven

Instead of hardcoding codex as the only special case:

  • If requiresOpenClawAuthBootstrap === false: return no harnessAuthProvider, skip initializeAuthProfile()
  • If forwardsAuthProfiles === false: do not resolve authProfileOrder
  • Use createEmptyAuthProfileStore() for these harnesses

3. Guard against stale auth-state poisoning

Ensure that resolveHarnessAuthProfileSelection() also respects harness metadata so that a stale disabledReason or disabledUntil in auth-state.json cannot block a harness that doesn't use OpenClaw auth.

4. Non-token preflight (optional)

For external-CLI harnesses, replace token validation with lightweight checks:

  • CLI binary exists and is executable
  • CLI credentials file exists and is readable
  • No need to validate token expiry — the CLI handles that

Workaround

Sync CLI credentials to OpenClaw auth-profiles.json periodically and clear stale auth-state.json flags. Example: a systemd timer that reads ~/.claude/.credentials.json and writes to both main and agent auth-profiles every 4 hours.

Impact

Any plugin harness that delegates auth to an external CLI tool will hit this issue when the stored OpenClaw tokens expire or get disabled. The fix is general — not Claude-specific.

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