#ACP Persistent Session Stuck After Gateway Restart

1 messages · Page 1 of 1 (latest)

plush magnet
#

Environment

  • OpenClaw 2026.4.12 (1c0672b), acpx 0.5.3, Node v25.9.0, macOS 15.4 arm64
  • ACP agent: acpx backend, claude agent, persistent mode
  • Bound to Discord standard text channel

Symptom

Every message to the ACP channel returns:

ACP error (ACP_TURN_FAILED): Internal error

The acpx backend works fine when invoked manually (acpx claude exec "hello" succeeds from the same cwd). Gateway logs show acp startup identity reconcile: checked=1 resolved=0 failed=1 on every restart.

Timeline

  1. Agent was working normally (successful prompts at 15:05 SGT)
  2. Multiple gateway restarts occurred (15:00–18:28) due to config edits
  3. After restarts, all ACP prompts fail — the gateway holds a stale backendSessionId for an acpx session that no longer exists
  4. 2 of 3 ACP agents stuck in state: "error", 1 is fine (idle)

Workarounds Attempted (All Failed)

  • /acp cancel — session state remains "error", identity not cleared
  • Manual edit of sessions.json (reset state to idle, clear identity) — gateway overwrites from in-memory state on next prompt
  • Deleting the .jsonl session file — no effect
split needleBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

teal gorgeBOT
chilly pastureBOT
#

Exec approval is required, but native chat exec approvals are not configured on Discord.

Approve it from the Web UI or terminal UI for now. Discord supports native exec approvals for this account. Configure channels.discord.execApprovals.approvers or commands.ownerAllowFrom; leave channels.discord.execApprovals.enabled unset/auto or set it to true.

chilly pastureBOT
# plush magnet Environment - OpenClaw 2026.4.12 (1c0672b), acpx 0.5.3, Node v25.9.0, macOS 15....

This smells like a real ACP restart/reconcile bug, not a bad acpx install.

Why I think that:

  • acpx claude exec "hello" works, so the backend itself is alive.
  • it broke only after gateway restarts
  • acp startup identity reconcile: checked=1 resolved=0 failed=1 is the tell that OpenClaw is restoring a persisted ACP identity it can no longer reattach to

Also, /acp cancel is probably the wrong lever here. Per docs, cancel stops the current turn. It does not tear down the session/binding. close is the one that should close the ACP session and remove bindings.

What I’d try, in order:

  1. In one bad channel, run:

    • /acp status
    • /acp sessions
    • /acp close
  2. If the channel is still pinned to the dead ACP session:

#
  • /unfocus
    • /new (or /reset)
    • then spawn/bind a fresh ACP session
  1. If the dead identity still resurrects after restart, stop the gateway completely, then clear the persisted ACP session entry plus its ACP binding while the gateway is down, then start clean. Editing sessions.json live usually loses, because in-memory state writes back over it. Deleting only the .jsonl transcript would not fix runtime identity state.

  2. For now, avoid gateway restarts while ACP sessions are active. There’s already a related restart bug where ACP child runtimes die on gateway restart: https://github.com/openclaw/openclaw/issues/52440

Given your exact timeline, I’d call this a bug/regression in the ACP restore path on 2026.4.12, especially if /acp close cannot clear a dead session.

Useful docs:

If you can paste the output of /acp status and /acp sessions from one broken channel after trying /acp close, I can help narrow whether it’s just a stuck binding or a deeper stale-identity restore bug.

plush magnet
#

Can a persistent ACP session continue a conversation indefinitely?

chilly pastureBOT
#

Yes, in principle, but with caveats.

  • A persistent ACP session can keep the same conversation/binding for a long time.
  • It is not truly immortal by default. The binding can be removed by close, unfocus, archive, idle timeout, or max-age expiry.
  • If you want it to stick around, use:
    • /session idle off
    • /session max-age off

Two important caveats:

  1. Conversation continuity != infinite raw context
    The session can continue, but history may get compacted/summarized over time. So “indefinite conversation” is yes, “infinite untouched transcript in memory” is no.

  2. Conversation continuity != backend process continuity
    With the current ACP restart behavior, I would not trust the live backend session to survive gateway restarts cleanly yet. That is separate from whether the chat binding is meant to persist.

Docs:

plush magnet
#

How to start a new session with ACP agent in a text channel, like having a new sesison with codex or claude code

chilly pastureBOT
#

In a normal text channel, the usual command is:

  • /acp spawn claude --bind here
  • or /acp spawn codex --bind here

That means “start a fresh ACP session and bind this channel to it”.

If the channel is already bound to an ACP session and you just want a fresh session in the same channel, use:

  • /new
  • or /reset

For ACP-bound chats, docs say /new and /reset reset the same bound ACP session in place.

If you want a separate thread instead of binding the channel itself:

  • /acp spawn claude --mode persistent --thread auto
#
  • /acp spawn codex --mode persistent --thread auto

Useful cleanup commands:

  • /acp close closes the ACP session and removes the binding
  • /unfocus removes the current binding without necessarily closing everything

So the short version is:

  • new ACP session in this text channel → /acp spawn <agent> --bind here
  • fresh start for an already bound ACP channel → /new

Docs:

If you want, I can also show the exact flow for “replace the broken bound session with a fresh Claude one in the same Discord channel.”