Skip to content

Followup queue drain crashes on CLI runtimes (claude-cli/codex-cli/gemini-cli): "Requested agent harness ... is not registered" #82847

Description

@joeykrug

Summary

createFollowupRunner unconditionally routes through runEmbeddedPiAgent, skipping the CLI-runtime dispatch branch the primary reply path uses. Any queued followup whose model resolves to a CLI runtime (claude-cli, codex-cli, google-gemini-cli) throws Requested agent harness "<runtime>" is not registered. and the queued message is silently dropped.

User-visible symptom: on bursty Signal threads (and any channel with queued followup delivery), only the most recent inbound that arrives while the agent is idle gets processed. Anything that lands mid-turn is queued, the drain crashes, and those messages vanish without surfacing an error.

Root cause

Throw site: selection-61FIEezO.js:9781-9799

const forced = pluginHarnesses.find((entry) => entry.id === runtime);
if (forced) return ...;
throw new Error(`Requested agent harness "${runtime}" is not registered.`);

Primary reply path (agent-runner.runtime-Dv_D_ax0.js:1030-1083) correctly checks for CLI runtimes first and routes them through runCliAgent:

const cliExecutionProvider = resolveCliRuntimeExecutionProvider(...) ?? provider;
if (isCliProvider(cliExecutionProvider, runtimeConfig)) {
  const result = await runCliAgent(...);
}

Followup queued runner (agent-runner.runtime-Dv_D_ax0.js:3034-3047) skips that branch entirely and always calls embedded Pi:

const fallbackResult = await runWithModelFallback({
  ...
  run: async (provider, model, runOptions) => {
    ...
    const result = await runEmbeddedPiAgent({ ... });

Embedded harness selection then looks up claude-cli (or codex-cli/google-gemini-cli) as a harness id — but those are registered as CLI backends by their plugins, not as runtime harnesses. Anthropic plugin registration:

  • register.runtime-CR-c-hRh.js:403-405api.registerCliBackend(buildAnthropicCliBackend())
  • Manifest extensions/anthropic/openclaw.plugin.json:54-56cliBackends entry, not a runtime harness

How to reproduce

  1. Configure a session whose agents.defaults.models[<id>].agentRuntime.id is claude-cli (or codex-cli/google-gemini-cli).
  2. Send a message that triggers a long-running turn (tools, subagents).
  3. While that turn is in flight, send a second message on the same channel. It enters the followup queue.
  4. When the primary turn completes, the followup drain runs → throws Requested agent harness "claude-cli" is not registered. → queued message is dropped.

Affects every queued lane that goes through createFollowupRunner: followup, collect, steer-backlog, cron/system-event followups.

Note: parent/child sharing the same runtime does not avoid the bug if that runtime is a CLI runtime. The dispatcher problem is independent of inheritance — it triggers whenever the queued lane resolves to any CLI runtime id.

Recommended fix (upstream)

In createFollowupRunner, before runEmbeddedPiAgent, perform the same CLI check the primary path does:

const cliExecutionProvider = resolveCliRuntimeExecutionProvider(...) ?? provider;
if (isCliProvider(cliExecutionProvider, runtimeConfig)) {
  return runCliAgent(...);  // with the queued run params
}
return runEmbeddedPiAgent(...);

Keeps claude-cli / codex-cli / google-gemini-cli as CLI backends instead of pretending they're harnesses.

Risk: affects all queued lanes — followup, collect, steer-backlog, cron/system-event followups, and any lane draining queued replies. Tests should cover:

  • Signal followup delivery for CLI runtimes
  • CLI session binding reuse across the drain
  • Fallback to embedded Pi for non-CLI runtimes (regression check)
  • Duplicate-delivery semantics through the CLI output bridge

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions