openclaw - 💡(How to fix) Fix [Bug] 2026.5.6 followup-agent path ignores agentRuntime.id=claude-cli — same root cause as #76265 in a parallel code path [1 comments, 2 participants]

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…
GitHub stats
openclaw/openclaw#80300Fetched 2026-05-11 03:16:36
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Timeline (top)
closed ×1commented ×1

The fix for #76265 closed the cron lane in dist/run-executor.runtime-*.js, but the same root-cause shape is still live in the followup-agent / queued-reply lane in dist/agent-runner.runtime-*.js. When an agent has agentRuntime.id=claude-cli, followup runs with payload model anthropic/claude-* are sent through the embedded Anthropic Messages API instead of the Claude CLI subprocess.

The chat path at lines 700-810 of agent-runner.runtime-BBZ7HfEt.js correctly calls resolveCliRuntimeExecutionProvider before isCliProvider and dispatches via runCliAgent. The followup queued-reply runner at lines 2287-2434 does not — it calls runEmbeddedPiAgent unconditionally:

// agent-runner.runtime-BBZ7HfEt.js (around line 2361)
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    let attemptCompactionCount = 0;
    try {
        const result = await runEmbeddedPiAgent({
            // ... no isCliProvider branch, no resolveCliRuntimeExecutionProvider call
        });

No isCliProvider branch, no resolveCliRuntimeExecutionProvider call. So anthropic/claude-* followups always hit the embedded API, even on agents bound to claude-cli.

Error Message

2026-05-10T12:26:30.827+02:00 [agents/tool-images] Image resized to fit limits: 1280x903px 88.9KB -> 91.1KB
2026-05-10T12:26:31.342+02:00 [agent/embedded] embedded run agent end: runId=... isError=true model=claude-opus-4-6 provider=anthropic error=LLM request rejected: You're out of extra usage. Add more at claude.ai/settings/usage and keep going.
2026-05-10T12:26:31.443+02:00 [agent/embedded] auth profile failure state updated: ... provider=claude-cli reason=billing window=disabled
2026-05-10T12:26:33.266+02:00 [agent/embedded] embedded run agent end: ... model=deepseek/deepseek-v4-pro provider=openrouter error=404 No endpoints found that support image input
Followup agent failed before reply: All models failed (2): anthropic/claude-opus-4-6: 400 ... (billing) | openrouter/deepseek/deepseek-v4-pro: 404 No endpoints found that support image input (model_not_found)

The auth-profile entry confirms the agent is on claude-cli, while the embedded run uses provider=anthropic for the same turn.

Root Cause

Root cause / proposed patch

Same shape as #76265 — wrap provider with resolveCliRuntimeExecutionProvider, then dispatch via isCliProvider/runCliAgent:

Fix Action

Fix / Workaround

The chat path at lines 700-810 of agent-runner.runtime-BBZ7HfEt.js correctly calls resolveCliRuntimeExecutionProvider before isCliProvider and dispatches via runCliAgent. The followup queued-reply runner at lines 2287-2434 does not — it calls runEmbeddedPiAgent unconditionally:

Root cause / proposed patch

Same shape as #76265 — wrap provider with resolveCliRuntimeExecutionProvider, then dispatch via isCliProvider/runCliAgent:

// dist/agent-runner.runtime-*.js, around line 2361
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    const cliExecutionProvider = resolveCliRuntimeExecutionProvider({
        provider,
        cfg: runtimeConfig,
        agentId: run.agentId
    }) ?? provider;
    if (isCliProvider(cliExecutionProvider, runtimeConfig)) {
        // dispatch via runCliAgent (mirroring the chat path at lines 700-810)
    } else {
        const result = await runEmbeddedPiAgent({
            // existing call
        });
    }
}

Code Example

// agent-runner.runtime-BBZ7HfEt.js (around line 2361)
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    let attemptCompactionCount = 0;
    try {
        const result = await runEmbeddedPiAgent({
            // ... no isCliProvider branch, no resolveCliRuntimeExecutionProvider call
        });

---

2026-05-10T12:26:30.827+02:00 [agents/tool-images] Image resized to fit limits: 1280x903px 88.9KB -> 91.1KB
2026-05-10T12:26:31.342+02:00 [agent/embedded] embedded run agent end: runId=... isError=true model=claude-opus-4-6 provider=anthropic error=LLM request rejected: You're out of extra usage. Add more at claude.ai/settings/usage and keep going.
2026-05-10T12:26:31.443+02:00 [agent/embedded] auth profile failure state updated: ... provider=claude-cli reason=billing window=disabled
2026-05-10T12:26:33.266+02:00 [agent/embedded] embedded run agent end: ... model=deepseek/deepseek-v4-pro provider=openrouter error=404 No endpoints found that support image input
Followup agent failed before reply: All models failed (2): anthropic/claude-opus-4-6: 400 ... (billing) | openrouter/deepseek/deepseek-v4-pro: 404 No endpoints found that support image input (model_not_found)

---

// dist/agent-runner.runtime-*.js, around line 2361
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    const cliExecutionProvider = resolveCliRuntimeExecutionProvider({
        provider,
        cfg: runtimeConfig,
        agentId: run.agentId
    }) ?? provider;
    if (isCliProvider(cliExecutionProvider, runtimeConfig)) {
        // dispatch via runCliAgent (mirroring the chat path at lines 700-810)
    } else {
        const result = await runEmbeddedPiAgent({
            // existing call
        });
    }
}
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

The fix for #76265 closed the cron lane in dist/run-executor.runtime-*.js, but the same root-cause shape is still live in the followup-agent / queued-reply lane in dist/agent-runner.runtime-*.js. When an agent has agentRuntime.id=claude-cli, followup runs with payload model anthropic/claude-* are sent through the embedded Anthropic Messages API instead of the Claude CLI subprocess.

The chat path at lines 700-810 of agent-runner.runtime-BBZ7HfEt.js correctly calls resolveCliRuntimeExecutionProvider before isCliProvider and dispatches via runCliAgent. The followup queued-reply runner at lines 2287-2434 does not — it calls runEmbeddedPiAgent unconditionally:

// agent-runner.runtime-BBZ7HfEt.js (around line 2361)
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    let attemptCompactionCount = 0;
    try {
        const result = await runEmbeddedPiAgent({
            // ... no isCliProvider branch, no resolveCliRuntimeExecutionProvider call
        });

No isCliProvider branch, no resolveCliRuntimeExecutionProvider call. So anthropic/claude-* followups always hit the embedded API, even on agents bound to claude-cli.

Impact

  • Image-bearing followups in particular fail visibly: the embedded API path returns 400 You're out of extra usage once the API budget is exhausted, then failover to a non-vision model (e.g. openrouter/deepseek/deepseek-v4-pro) fails with 404 No endpoints found that support image input. The CLI subprocess still has Pro-plan capacity at the time.
  • Same silent transport swap as #76265: operators see provider=anthropic in followup logs while the agent's agentRuntime.id says claude-cli. Easy to misdiagnose as auth/billing.

Reproduction

  1. Configure an agent with agentRuntime.id = claude-cli. Confirm chat turns hit the CLI subprocess.
  2. Bind the agent to a chat channel that produces followup runs (e.g. Telegram with image attachments).
  3. Send a message with an image. Tail gateway logs.
  4. Observe: an [agent/embedded] embedded run fires for the followup with model=claude-opus-4-6 provider=anthropic. If the embedded Anthropic API budget is exhausted, the run fails with out of extra usage. If the failover chain doesn't lead with a vision-capable model, it then fails again with No endpoints found that support image input.

Logs

2026-05-10T12:26:30.827+02:00 [agents/tool-images] Image resized to fit limits: 1280x903px 88.9KB -> 91.1KB
2026-05-10T12:26:31.342+02:00 [agent/embedded] embedded run agent end: runId=... isError=true model=claude-opus-4-6 provider=anthropic error=LLM request rejected: You're out of extra usage. Add more at claude.ai/settings/usage and keep going.
2026-05-10T12:26:31.443+02:00 [agent/embedded] auth profile failure state updated: ... provider=claude-cli reason=billing window=disabled
2026-05-10T12:26:33.266+02:00 [agent/embedded] embedded run agent end: ... model=deepseek/deepseek-v4-pro provider=openrouter error=404 No endpoints found that support image input
Followup agent failed before reply: All models failed (2): anthropic/claude-opus-4-6: 400 ... (billing) | openrouter/deepseek/deepseek-v4-pro: 404 No endpoints found that support image input (model_not_found)

The auth-profile entry confirms the agent is on claude-cli, while the embedded run uses provider=anthropic for the same turn.

Root cause / proposed patch

Same shape as #76265 — wrap provider with resolveCliRuntimeExecutionProvider, then dispatch via isCliProvider/runCliAgent:

// dist/agent-runner.runtime-*.js, around line 2361
run: async (provider, model, runOptions) => {
    const authProfile = resolveRunAuthProfile(run, provider, { config: runtimeConfig });
    const cliExecutionProvider = resolveCliRuntimeExecutionProvider({
        provider,
        cfg: runtimeConfig,
        agentId: run.agentId
    }) ?? provider;
    if (isCliProvider(cliExecutionProvider, runtimeConfig)) {
        // dispatch via runCliAgent (mirroring the chat path at lines 700-810)
    } else {
        const result = await runEmbeddedPiAgent({
            // existing call
        });
    }
}

resolveCliRuntimeExecutionProvider is already imported in this file (ct from ./io-*.js).

Environment

  • OpenClaw 2026.5.6 (c97b9f7)
  • macOS Darwin 25.4.0
  • npm global install
  • Agent setup: agentRuntime.id = claude-cli, primary model anthropic/claude-opus-4-6, fallbacks [openai-codex/gpt-5.5, xai/grok-4.3, openrouter/deepseek/deepseek-v4-pro]

Related

  • #76265 — same root cause in the cron lane, fixed in run-executor.runtime-*.js. The fix did not extend to agent-runner.runtime-*.js.
  • #75753 — claude-cli/* allowlist drop forces operators onto anthropic/*, where this bug surfaces.

Workaround for affected operators: put a vision-capable non-Anthropic model first in the fallback chain (e.g. openai-codex/gpt-5.5) so image-bearing followups still complete when the embedded API rejects on billing.

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

openclaw - 💡(How to fix) Fix [Bug] 2026.5.6 followup-agent path ignores agentRuntime.id=claude-cli — same root cause as #76265 in a parallel code path [1 comments, 2 participants]