openclaw - 💡(How to fix) Fix Per-channel ACP spawn policy: prevent runaway acp sessions from non-interactive channels (Telegram DM, etc.)

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…

ACP sessions spawned from non-interactive channels (e.g., Telegram DM) can produce a runaway loop of "Background task failed: permission prompt unavailable in non-interactive mode" completion events that flood the chat. There is no rate-limiting or coalescing on these announcements, and the parent session has no clean way to silence them once the child is stuck.

Error Message

"acpSpawnPolicy": "deny" // or "allow" | "warn" When set to "deny", sessions_spawn(runtime="acp", ...) from that channel returns an error before any process is created. "warn" returns a warning the agent can route around. Default could be "allow" for backward compat.

Root Cause

Two things compound: (1) Telegram DM is the most common operator surface in practice, and (2) ACP coding sessions are exactly the kind of task an agent reaches for to delegate complex work. So the failure mode sits squarely at the intersection of the two most common patterns. Per-channel policy lets operators opt out of the failure mode entirely without disabling ACP globally.

Fix Action

Fix / Workaround

Workaround in use today

I added a hard rule to the agent's MEMORY.md: never spawn ACP from Telegram DM. This works only because the agent reads MEMORY.md on every session startup. Anyone running OpenClaw without that workaround is exposed to the same failure mode.

Code Example

{
  "channels": {
    "telegram": {
      "acpSpawnPolicy": "deny"   // or "allow" | "warn"
    }
  }
}
RAW_BUFFERClick to expand / collapse

Summary

ACP sessions spawned from non-interactive channels (e.g., Telegram DM) can produce a runaway loop of "Background task failed: permission prompt unavailable in non-interactive mode" completion events that flood the chat. There is no rate-limiting or coalescing on these announcements, and the parent session has no clean way to silence them once the child is stuck.

Repro

  1. From a Telegram DM session (channel inherently non-interactive — no approval UI), call sessions_spawn with runtime="acp", agentId="codex", mode="session", thread=true.
  2. Brief the child to do work that would normally need tool approvals (file writes, exec, etc.).
  3. Child hits a permission prompt; acpx.config.nonInteractivePermissions="deny" correctly denies, but the child retries in a loop.
  4. Each retry emits a 'Background task done/failed' event back to the parent via the inter-session announcement channel.
  5. Parent's chat is flooded with 50+ identical-shaped completion events. Cannot be silenced from the parent side.

Observed

Two separate incidents (2026-05-03 Mathom build, 2026-05-08 BabyYoda build) traced to this exact pattern. Each wasted significant user time and required manual intervention to recover.

Existing config acpx.config.nonInteractivePermissions="deny" is the right primitive but isn't sufficient because (a) the child agent keeps retrying after denial, and (b) the parent has no coalescing on completion events.

Proposed fix (priority order)

A. Per-channel ACP spawn policy (preferred)

{
  "channels": {
    "telegram": {
      "acpSpawnPolicy": "deny"   // or "allow" | "warn"
    }
  }
}

When set to "deny", sessions_spawn(runtime="acp", ...) from that channel returns an error before any process is created. "warn" returns a warning the agent can route around. Default could be "allow" for backward compat.

B. Completion event coalescing

In the inter-session announcement layer, suppress or fold consecutive identical-shape completion events from the same child within an N-second window (configurable, default 30s). This handles the broader 'noisy child' class even when ACP is allowed.

C. Bound child retry on permission denial

When acpx denies a tool call due to nonInteractivePermissions="deny", surface the denial to the child with a flag that prevents auto-retry. Force the child to either succeed without that tool or terminate cleanly. This is upstream of A/B but most invasive.

Workaround in use today

I added a hard rule to the agent's MEMORY.md: never spawn ACP from Telegram DM. This works only because the agent reads MEMORY.md on every session startup. Anyone running OpenClaw without that workaround is exposed to the same failure mode.

Environment

  • OpenClaw runtime (current as of 2026-05-08)
  • Channel: telegram
  • Affected ACP backend: acpx (codex agent)
  • acp.maxConcurrentSessions: 3 — also worth reconsidering as default; even 3 runaway children produces 3× the spam

Why this matters

Two things compound: (1) Telegram DM is the most common operator surface in practice, and (2) ACP coding sessions are exactly the kind of task an agent reaches for to delegate complex work. So the failure mode sits squarely at the intersection of the two most common patterns. Per-channel policy lets operators opt out of the failure mode entirely without disabling ACP globally.

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 Per-channel ACP spawn policy: prevent runaway acp sessions from non-interactive channels (Telegram DM, etc.)