#ACP doesn't appear to be responding all the way
91 messages · Page 1 of 1 (latest)
First, what does openclaw --version show?
To tell “ACP stopped” vs “Discord delivery is broken”, I’d check these in order:
-
In the same thread, run:
/acp status/tasks/acp sessions/acp doctor
-
How to read that:
- If
/acp statusfinds the session and/tasksshows it still active, the ACP runtime is probably still alive. Then I’d suspect reply delivery/relay. - If
/acp statussays it cannot resolve the session, or/acp sessionsdoes not show it, that points to binding/session state. - If
/acp doctorcomplains about backend/dispatch, that is wiring/config.
- If
-
On the machine running OpenClaw:
openclaw status --all
openclaw gateway statusopenclaw logs --follow
A very common cause here is ACP dying when it tries to write files or run commands in non-interactive mode. In logs, look for:
AcpRuntimeError: Permission prompt unavailable in non-interactive mode
That matches the “it says it’s going to do something, then goes quiet” pattern really well.
If you are using thread-bound ACP on Discord, also verify these config flags:
{
acp: {
enabled: true,
dispatch: { enabled: true },
},
session: {
threadBindings: { enabled: true },
},
channels: {
discord: {
threadBindings: {
enabled: true,
spawnAcpSessions: true,
},
},
},
}
One nuance: if you used /acp spawn ... --bind here, spawnAcpSessions is not required. That flag matters when OpenClaw needs to create a child thread.
If you paste:
openclaw --version/acp status/tasks/acp doctor
I can help narrow it down fast.
Docs:
OpenClaw 2026.4.11 (769908e)
give me the commands to run on the VPs itself. i don't want to debug through discord
acp status shows nothing, tasks also shows nothing
all of the other commands says done and doesn't show anything
Yep. On the VPS, I’d run this exact set.
1. Baseline health
openclaw status
openclaw status --all
openclaw gateway status
openclaw health --verbose
2. ACP backend and plugin state
openclaw plugins inspect acpx
openclaw plugins doctor
openclaw config get acp --json
openclaw config get plugins.entries.acpx --json
3. Check the binding/dispatch flags
openclaw config get acp.enabled
openclaw config get acp.dispatch.enabled
openclaw config get session.threadBindings.enabled
openclaw config get channels.discord.threadBindings.enabled
openclaw config get channels.discord.threadBindings.spawnAcpSessions
4. Check the ACP permission mode, this is a very common cause
openclaw config get plugins.entries.acpx.config.permissionMode
openclaw config get plugins.entries.acpx.config.nonInteractivePermissions
5. Tail logs live, then send one test message from Discord
openclaw logs --follow | grep -Ei 'acp|acpx|discord|deliver|delivery|reply|send|permission|error|exception'
6. If it looks hung after work supposedly finished
ps aux | grep -Ei 'acpx|codex|claude|cursor|gemini' | grep -v grep
How to read the results
-
Discord message arrives, ACP logs start, then you see an ACP error
-> ACP/runtime problem -
Discord message arrives, ACP completes, but no outbound Discord send
-> Discord delivery / session piping problem
-
Discord message arrives, but nothing ACP-related happens after that
-> dispatch/binding problem -
It says it’s going to edit/run something, then dies
-> very often this:
AcpRuntimeError: Permission prompt unavailable in non-interactive mode
That usually means ACPX is trying to do a write/exec with a permission mode that cannot prompt interactively.
One nuance: if you used --bind here, spawnAcpSessions is not required. That flag matters when OpenClaw needs to create a child thread.
If you paste the outputs from steps 2 through 5, I can usually tell pretty quickly which side is broken.
Docs:
That narrows it a lot.
If /acp status shows nothing and /tasks shows nothing, I would not blame Discord reply piping first. Usually that means there is no bound/active ACP session by the time you check, so the problem is more likely:
- ACP session never got created/bound
- it died immediately
- dispatch/binding metadata got dropped
On the VPS, I’d do this next.
1. Reproduce while tailing logs
openclaw logs --follow | grep -Ei 'acp|acpx|discord|bind|thread|session|deliver|reply|send|permission|error|exception'
Then send one message in the Discord thread and watch what happens.
2. See whether any ACP sessions exist at all
openclaw sessions --all-agents --active 120
openclaw sessions --all-agents --json | grep -n 'acp:'
3. Verify ACP + Discord binding config
openclaw config get acp.enabled
openclaw config get acp.dispatch.enabled
openclaw config get session.threadBindings --json
openclaw config get channels.discord.threadBindings --json
openclaw config get plugins.entries.acpx --json
4. Check the common ACPX failure mode
openclaw config get plugins.entries.acpx.config.permissionMode
openclaw config get plugins.entries.acpx.config.nonInteractivePermissions
What the results mean
-
Discord message appears in logs, but no ACP spawn/bind/session log after it
-> dispatch or thread binding issue -
ACP session appears, then error
-> ACP runtime/plugin/permissions issue -
ACP session completes, but Discord send fails
-> reply delivery problem -
No
:acp:sessions at all, even right after repro
-> session is not sticking around, this is probably not just “Discord didn’t pipe the reply”
If you paste the log lines from the repro window, I can help read them. My first suspicion from your symptom is still ACPX permissions or binding, not Discord transport.
Docs:
If everything is coming back blank/“done”, I’d stop chasing ACP for a second.
That pattern usually means you are not looking at the same Gateway instance/config that Discord is actually using, or the RPC probe/log target is wrong.
Run these next on the VPS
openclaw gateway status
openclaw gateway status --require-rpc
openclaw gateway status --deep
openclaw health --verbose
What to look for in gateway status
Pay attention to these lines:
Probe target:Listening:
Config (cli):Config (service):Last gateway error:- the file log path
If Config (cli) and Config (service) are different, you’re editing one config while the service is running another. That would explain the “blank everywhere” behavior.
Then tail the real log file directly
Use the log path shown by openclaw gateway status, or fall back to:
tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)"
Then reproduce once from Discord.
Short read on what you already found
/acp status empty + /tasks empty means there is not an active bound ACP session in that thread at check time.
So this is probably not just “Discord didn’t pipe the reply back”. More likely:
- wrong Gateway instance/config
- ACP never bound
- ACP died immediately
- duplicate Gateway/service install
If gateway status --deep shows multiple installs/instances, that’s a huge clue.
If Config (cli) and Config (service) differ, docs say the fix is:
openclaw gateway install --force
Run that from the same profile/environment you actually want the service to use.
Docs:
no new lines are showing in the tail log
Ah, that’s a really useful signal.
If the log tail stays completely silent while you trigger a Discord message, then one of two things is happening:
- the
grepfilter is hiding everything, or - you are watching the wrong Gateway instance/log
First, remove the filter
openclaw logs --follow
If that is still totally silent during a repro, then I’d assume instance/config drift.
Next, check the actual live service
openclaw gateway status --deep
openclaw gateway status --json
ps -ef | grep -i '[o]penclaw\|[n]ode.*openclaw'
ss -ltnp | grep 18789
What I’d look for
Config (cli)vsConfig (service)mismatch- multiple OpenClaw/gateway processes
- a different process listening on
18789 - a different log path than the one you tailed
Also, make sure you’re running those commands as the same Linux user that the daemon runs under.
If openclaw logs --follow is silent and Discord is definitely receiving messages, you are almost certainly not attached to the live gateway process. That is a much stronger lead than ACP itself right now.
If you paste the output of:
openclaw gateway status --deep
I can help read it. Docs: https://docs.openclaw.ai/help/faq
openclaw logs --follow | grep -Ei 'acp|acpx|discord|bind|thread|session|deliver|reply|send|permission|error|exception'
2026-04-14T04:04:20.339Z warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_agent_end","tags":["error_handling","lifecycle","agent_end","assistant_error"],"runId":"0f0e0189-c0e4-4fa3-8608-80fe7765782b","isError":true,"error":"LLM request timed out.","failoverReason":"timeout","model":"openrouter/free","provider":"openrouter","rawErrorPreview":"Provider timed out after 20308ms","rawErrorHash":"sha256:d6f5b586bd97","providerRuntimeFailureKind":"timeout"} embedded run agent end
2026-04-14T04:06:47.933Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 107ms conn=6429cfa8…59b7 id=45e3f420…eebb
2026-04-14T04:06:48.812Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 60ms conn=62b513dc…7d3b id=1fb19506…3024
2026-04-14T04:07:07.944Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 59ms conn=62b513dc…7d3b id=3655bf62…b749
2026-04-14T04:07:10.975Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 66ms conn=62b513dc…7d3b id=b2eeb238…071c
2026-04-14T04:07:13.756Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 56ms conn=62b513dc…7d3b id=c0850efd…b6bb
2026-04-14T04:07:19.637Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 68ms conn=62b513dc…7d3b id=7f351038…79f1
2026-04-14T04:07:24.102Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 73ms conn=62b513dc…7d3b id=a4564088…56f2
2026-04-14T04:07:28.825Z info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.list 64ms conn=62b513dc…7d3b id=82d9d2cd…26ea
2026-04-14T08:25:30.155Z info Session stores: 1 (claude)
2026-04-14T08:25:30.192Z info Sessions listed: 5
2026-04-14T08:25:30.198Z info claude group agent:claude:acp...e6955e 1m ago openrouter/free unknown/200k (?%) id:184ede52-7835-4d7c-9b55-e3a026abef6b
openclaw sessions --all-agents --active 120
openclaw sessions --all-agents --json | grep -n 'acp:'
🦞 OpenClaw 2026.4.11 (769908e) — I've read more man pages than any human should—so you don't have to.
Session stores: 1 (claude)
Sessions listed: 5
Filtered to last 120 minute(s)
Agent Kind Key Age Model Tokens (ctx %) Flags
claude group agent:claude:acp...e6955e 1m ago openrouter/free unknown/200k (?%) id:184ede52-7835-4d7c-9b55-e3a026abef6b
claude group agent:claude:dis...022410 7m ago openrouter/free unknown/200k (?%) id:485e4af8-2449-4b46-ad78-f605088181ca
claude direct agent:claude:cro...8071b4 20m ago openrouter/free 10k/200k (5%) system id:594ef4aa-6690-472b-9d74-d391ae80dbf9
claude direct agent:claude:cro...80dbf9 20m ago openrouter/free 10k/200k (5%) system id:594ef4aa-6690-472b-9d74-d391ae80dbf9
claude direct agent:claude:cro...bc2b30 1h ago openrouter/free 10k/200k (5%) system id:c71d868c-e205-4ad0-93e1-d2acfebc2b30
14: "key": "agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e",
466: "key": "agent:claude:acp:f0fd6bbd-4f6e-42b7-97c8-21e5fc82933d",
517: "key": "agent:claude:acp:efe4c651-e7a2-4476-9252-442f32d893ac",
534: "key": "agent:claude:acp:faf9b908-2233-47cd-92ff-7c8d027c6d56",
568: "key": "agent:claude:acp:21a105bc-249d-4396-85bf-9f2ec68cb89d",
616: "key": "agent:claude:acp:840ce780-a689-46cf-88a1-18e21ba21179",
629: "key": "agent:claude:acp:aef754ba-e97a-4dba-af75-3984d9376767",
642: "key": "agent:claude:acp:86dffa00-07b4-49e4-abcf-00ac4cf2c74a",
655: "key": "agent:claude:acp:0daccdef-0285-4b0c-8a1c-e37ee9fa641e",
672: "key": "agent:claude:acp:8f35cfee-d8c3-4ed0-ab55-1059a0a1b199",
openclaw config get acp.enabled
openclaw config get acp.dispatch.enabled
openclaw config get session.threadBindings --json
openclaw config get channels.discord.threadBindings --json
openclaw config get plugins.entries.acpx --json
🦞 OpenClaw 2026.4.11 (769908e) — More integrations than your therapist's intake form.
true
🦞 OpenClaw 2026.4.11 (769908e) — If it works, it's automation; if it breaks, it's a "learning opportunity."
true
{
"enabled": true,
"idleHours": 24,
"maxAgeHours": 48
}
{
"spawnAcpSessions": true,
"enabled": true
}
{
"enabled": true,
"config": {
"permissionMode": "approve-all",
"timeoutSeconds": 120
}
}
Nice, this is enough to say a few real things.
What your output tells us
-
There is an ACP session in the store
agent:claude:acp...e6955e- so ACP is not completely absent
-
You have at least one upstream timeout in the stack
LLM request timed out- provider/model shown there is
openrouter/free
-
Your grep output is not showing the actual Discord repro
- the interesting lines are from
04:04to04:07 - the only fresh
08:25lines are from your ownopenclaw sessionscommand
- the interesting lines are from
So right now I would say:
- this does not look like a simple “Discord swallowed the reply”
- it looks more like session binding/routing drift, and possibly runtime timeouts on top
Next thing I’d do
Run raw logs, no grep:
openclaw logs --follow
Then reproduce once from Discord.
If you still do not see fresh inbound Discord / ACP activity at the moment of repro, you are almost certainly not watching the live gateway handling that thread.
Also run:
openclaw gateway status --deep
openclaw sessions --all-agents --json
My current read
- stored ACP session exists
- current thread probably is not bound to it anymore
- and there is at least one timeout issue in the ACP/model path
If you paste openclaw gateway status --deep, I can probably tell you pretty quickly whether this is a wrong-instance problem or a binding problem.
openclaw config get plugins.entries.acpx.config.permissionMode
openclaw config get plugins.entries.acpx.config.nonInteractivePermissions
🦞 OpenClaw 2026.4.11 (769908e) — I'm the assistant your terminal demanded, not the one your sleep schedule requested.
approve-all
🦞 OpenClaw 2026.4.11 (769908e) — You had me at 'openclaw gateway start.'
Config path not found: plugins.entries.acpx.config.nonInteractivePermissions
Okay, this is much clearer now.
What this proves
- ACP sessions are being created and stored
- the fresh one is:
agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e - the other
acp:keys are just older stored sessions, that part is normal
So this is not “ACP never started”.
My read now
Because you have a fresh ACP session in the store, but /acp status in the thread was empty, the most likely problem is:
- thread/conversation binding is broken or stale
- less likely, pure Discord outbound delivery
- plus you may have timeout noise from that
openrouter/freepath
In other words, the ACP runtime exists, but the thread probably is not resolving to the right ACP session key anymore.
So the likely fix path is
- rebind/focus the thread to the current ACP session, or
- close and respawn a fresh ACP session
If you want the cleanest proof, use that exact session key once:
/acp status agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
If that works, ACP is alive and the problem is binding/routing, not “Discord ate the reply”.
If you want, I can give you the shortest “recover this thread” sequence next, either with /focus or with a clean respawn. Docs: https://docs.openclaw.ai/tools/acp-agents
Yep, those settings all look correct.
So at this point we can rule out:
acp.enabledacp.dispatch.enabled- Discord thread binding flags
- ACPX plugin being disabled
- ACPX permission prompts blocking writes
What’s left
Given all the outputs so far, the remaining likely causes are:
- this specific Discord thread lost/missed its ACP binding, or
- the ACP session/runtime is timing out upstream
(that earlierLLM request timed outline still matters)
Best discriminator now
Use the exact session key you found:
/acp status agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
How to read it:
- If that works, ACP is there, and your problem is thread routing/binding
- If that fails / looks dead, the problem is the session/runtime itself
Fast recovery options
If you want to recover the thread:
/focus agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
Or, clean reset:
/acp close
/acp spawn claude --bind here
So, big picture, I think you’ve already verified this is not a global ACP config problem. It’s now down to per-thread binding vs that specific session timing out.
That part is actually reassuring.
Config path not found: plugins.entries.acpx.config.nonInteractivePermissions just means that key is not explicitly set.
Since you already have:
permissionMode = approve-all
I would stop chasing ACPX permissions. With approve-all, ACPX should not be blocking on write/exec approval prompts.
So now the picture looks like this:
- global ACP config is fine
- thread binding config is fine
- ACPX permissions are fine
- there is an ACP session in the store
- you did see an upstream
LLM request timed out
So the remaining likely causes are
- stale/missing binding for this thread
- upstream model/provider timeout, not ACPX itself
Also, your ACPX timeout is 120s, but the log timeout you saw was around 20s, which points more at the provider route than the ACPX wrapper.
My recommendation
At this point I’d do one of these:
/focus agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
or just clean-reset it:
/acp close
/acp spawn claude --bind here
And for testing, I’d avoid that flaky openrouter/free path if you can. I think you’re down to binding plus maybe provider timeout, not Discord transport.
08:25:30+00:00 info Filtered to last 120 minute(s)
08:25:30+00:00 info Agent Kind Key Age Model Tokens (ctx %) Flags
08:25:30+00:00 info claude group agent:claude:acp...e6955e 1m ago openrouter/free unknown/200k (?%) id:184ede52-7835-4d7c-9b55-e3a026abef6b
08:25:30+00:00 info claude group agent:claude:dis...022410 7m ago openrouter/free unknown/200k (?%) id:485e4af8-2449-4b46-ad78-f605088181ca
08:25:30+00:00 info claude direct agent:claude:cro...8071b4 20m ago openrouter/free 10k/200k (5%) system id:594ef4aa-6690-472b-9d74-d391ae80dbf9
08:25:30+00:00 info claude direct agent:claude:cro...80dbf9 20m ago openrouter/free 10k/200k (5%) system id:594ef4aa-6690-472b-9d74-d391ae80dbf9
08:25:30+00:00 info claude direct agent:claude:cro...bc2b30 1h ago openrouter/free 10k/200k (5%) system id:c71d868c-e205-4ad0-93e1-d2acfebc2b30
08:27:18+00:00 info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ logs.tail 58ms conn=239f99d7…ac14 id=98f37135…e91d
08:27:22+00:00 info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ logs.tail 423ms conn=ff396a20…8335 id=9e9bfd1e…c608
08:32:53+00:00 info gateway/ws {"subsystem":"gateway/ws"} ⇄ res ✓ sessions.resolve 54ms conn=30398448…7a3a id=a7d4c5e7…677f
Yep, I think we’ve squeezed most of the signal out of the VPS side now.
That sessions.resolve line is useful. It means the gateway can see and resolve session targets. What we are not seeing is evidence of:
- an ACP turn actually running for this thread
- a Discord outbound send failing
So my read is now pretty firm:
Most likely
This is a binding / routing problem for this thread, not a global ACP config problem and not a simple Discord transport failure.
Why
You’ve already shown:
- ACP is enabled
- dispatch is enabled
- Discord thread bindings are enabled
- ACPX is enabled with
approve-all - ACP sessions exist in the store
- session resolution works
What’s missing is the thread actually staying attached to the right ACP session and using it.
Fastest recovery path
I’d stop digging on the VPS and do this in the thread:
/focus agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
If that still behaves weird, then just reset it cleanly:
/acp close
/acp spawn claude --bind here
If the fresh spawn also breaks
At that point I’d call it bug territory and file an issue with:
openclaw --version- the config outputs you pasted
- the
openclaw sessions --all-agents --active 120output - the relevant log lines
Issue tracker: https://github.com/openclaw/openclaw/issues
So, short version, I do not think this is “Discord not piping replies through”. I think this specific thread/session binding is getting lost or not reused correctly.
JarvisClaw: ACP status:
session: agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
backend: acpx
agent: claude
acpx session id: 7a778d6f-f293-4d15-9eca-254e9c8e20e8
acpx record id: agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
sessionMode: persistent
state: idle
runtimeOptions: cwd=/home/jarvis/.openclaw/workspace
capabilities: session/set_config_option, session/set_mode, session/status
lastActivityAt: 2026-04-14T08:33:13.550Z
runtime: session=agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e backendSessionId=7a778d6f-f293-4d15-9eca-254e9c8e20e8 pid=226747 open
runtimeDetails: {"cwd":"/home/jarvis/.openclaw/workspace","lastUsedAt":"2026-04-14T08:33:13.382Z","closed":false}
Perfect, that answers the main question.
The ACP agent did not stop
This status says:
state: idleclosed: falsepid=226747 open- persistent session is still there
So the ACP runtime is alive and open. It is just not currently processing.
What that means
This points away from “the ACP agent crashed” and toward one of these:
- the last turn ended without a visible reply, or
- the thread is not routing follow-up messages into that session correctly, or
- ACP can run, but the return delivery back to Discord is flaky
Best final discriminator
Try an explicit targeted steer, so we bypass normal thread routing:
/acp steer --session agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e reply with exactly PONG
How to read it:
- If you get
PONGback, ACP runtime + return path are fine, and the broken piece is thread binding/routing of normal messages - If you do not get
PONGback, then ACP-to-Discord delivery is the suspect
So, short version, you’ve now verified:
- ACP session exists
- ACP process is alive
- ACP backend is open
That’s a good catch. We’re down to routing/binding vs outbound delivery, not “did the ACP agent die?”. Docs: https://docs.openclaw.ai/tools/acp-agents
it is executing a long playwright test, and no more reply after. can you tell me more about the 120s timeout ?
Yep. That 120s is the ACPX runtime turn timeout.
What it means
- It is not the lifetime of the persistent ACP session
- It is the timeout for a single embedded runtime turn
- So the session can stay
openand later showstate: idle, even if the turn got cut off
That matches your symptom pretty well:
- ACP session still exists
- process is still open
- long Playwright test runs
- no final reply comes back
It is separate from these other timeouts
- provider/model timeout
for example the earlieropenrouter/freetimeout you saw
- thread binding idleHours/maxAgeHours
those are conversation binding limits, not per-turn runtime limits - Playwright/test timeout inside the repo itself
that is whatever the test runner/browser action is configured to use
So for long Playwright work
If the agent waits for the test to finish before replying, 120s can absolutely be too short.
How to raise it
openclaw config set plugins.entries.acpx.config.timeoutSeconds 300
openclaw gateway restart
Docs show 180 as an example, but for long browser tests I’d probably start with 300.
My read
At this point, I think you may have two things interacting:
- long-running Playwright work hitting the ACPX per-turn timeout
- some thread/routing weirdness that makes the failure mode look silent
Docs: https://docs.openclaw.ai/tools/acp-agents
Glad we caught that, this one was slippery.
5 minutes is not enough, this is a slow vps. 2 core 4gb ram. what is the maximum timeout seconds it supports
There is a hard cap for ACP runtime timeouts: 86,400 seconds (24 hours).
That comes from the ACP runtime option validator, which accepts only a positive integer from 1 to 86400.
A couple nuances though:
plugins.entries.acpx.config.timeoutSecondsis the default/acp timeout <seconds>is the per-session override- The 24h cap is definitely enforced on the ACP runtime/session option path
So if you want longer than 5 minutes, you can safely go much higher. For a slow Playwright run on a 2 core / 4 GB VPS, I’d try:
900seconds (15 min), or1800seconds (30 min)
before jumping to something huge.
Example
Global default:
openclaw config set plugins.entries.acpx.config.timeoutSeconds 1800
openclaw gateway restart
Per session:
/acp timeout 1800
I would avoid setting it absurdly high unless you need it, because then genuinely stuck turns take forever to fail. Docs: https://docs.openclaw.ai/tools/acp-agents
how do i recover from a stuck turn ?
I’d recover a stuck ACP turn in this order:
1. Cancel just the current turn
/acp cancel
If you want to target the exact session:
/acp cancel agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
2. Check whether the session is still healthy
/acp status
If it shows idle and open, the turn is gone but the session survived.
3. Rebind the thread if needed
/focus agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
4. If the session itself feels wedged, close and respawn
/acp close
/acp spawn claude --bind here
5. If it is still hung on the VPS side
Docs call out stale acpx processes as a real failure mode:
ps aux | grep acpx
If you see an obviously stale one that survived cancel/close, kill that process, then retry.
For long Playwright runs
Before rerunning, increase the timeout so you do not hit the same wall again:
/acp timeout 1800
So the short version is:
cancel → status → focus → close/respawn → kill stale acpx only if needed
what if an acp session is stuck how do i access the harness to unstuck the process
Short answer, you generally don’t attach to the ACP harness interactively.
ACP sessions run non-interactively, so there is no supported “open a shell into the harness” / TTY attach flow through OpenClaw today.
What you can do
From chat
/acp status
/acp cancel
/acp steer ...
/acp close
From the VPS
Use the PID from /acp status, then inspect the process directly:
ps -fp <pid>
pstree -ap <pid>
lsof -p <pid> | head
That tells you what the harness is doing and whether it is still alive.
If it is truly wedged
There usually is not an “unstick” command inside the harness. The normal recovery is:
/acp cancel- if that fails,
/acp close - if the host process is still stuck, kill the PID on the VPS
- respawn the session
So the model is really:
- inspect the harness by PID
- control it through
/acp ... - kill + respawn if it is genuinely hung
If you want, I can give you a minimal “safe stuck harness playbook” for Linux, just the exact 4 or 5 commands.
After the session reconnects how do i see the past messages ?
Two slightly different things here:
1. What you can see
If it reconnects in the same Discord thread, the past chat is just the thread history.
If you want the stored OpenClaw transcript, use:
/export-session
That exports the current session to HTML.
You can also inspect transcripts on disk under:
~/.openclaw/agents/<agentId>/sessions/
Use openclaw sessions --all-agents --json first if you need to identify the right agent/session.
2. What the ACP harness sees after reconnect
When an ACP session is resumed, OpenClaw replays the stored user + assistant text history via session/load.
One important limit: it does not fully reconstruct old tool/system history, only the text conversation.
So short version:
- human view: thread history or
/export-session - harness view on reconnect: prior user/assistant text is replayed, tool history is partial/not rebuilt
Docs:
command to reconnect ? And how do i check if im disconnected
If by “reconnect” you mean re-attach this thread to an existing ACP session, the command is:
/focus agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
There is not really a separate /acp reconnect command, /focus is the rebind/reconnect move.
How to tell if you’re disconnected
Check the current thread binding
/acp status
- if it shows a session, this thread is connected/bound
- if it shows nothing / cannot resolve, this thread is not currently bound
Check the session directly
/acp status agent:claude:acp:c239adee-bf2f-48b9-b6d5-c883b1e6955e
- if this works, the ACP session itself still exists
- if plain
/acp statusdoes not work, then the thread is disconnected from that session
Optional
/agents
That helps show what is actually bound to the current thread.
If you want a clean reconnect instead of rebinding
/acp close
/acp spawn claude --bind here
So the short version is:
- reconnect existing session →
/focus <session-key> - check if thread is disconnected →
/acp status - check if session still exists anyway →
/acp status <session-key>
Is it expected that the acp agents responses is not streamed to us but send it all at once after the turn is done ? How would i see intermitten progress ?
Yes, on Discord that is mostly expected right now.
For chat-bound ACP sessions, you often get the final reply at turn completion, not a true live token-by-token or terminal-style stream.
So how do you see intermittent progress?
In chat
The main thing you can check is:
/acp status
That tells you whether the session is running / idle, plus runtime details, but it is not a rich live progress feed.
On the host
When ACP is started with progress streaming enabled programmatically, OpenClaw can expose a session-scoped stream log like:
<sessionId>.acp-stream.jsonl
That file can be tailed for relay history when available.
Important limitation
There is not really a “watch the harness terminal live in Discord” experience today. That’s why long Playwright runs can feel silent until the turn finishes, times out, or gets unstuck.
So short version:
- final reply all at once: yes, that can be normal
- lightweight status:
/acp status - real intermittent relay history: host-side stream log, when available
- true live terminal stream in Discord: not really today
do other channels like telegram support stream or atleast on going progress ?
Yep.
Channel support, short version
- Telegram: supports
partialandblockpreview streaming - Discord: supports
partialandblockpreview streaming - Slack: supports
partial,block, and a real distinctprogressmode
For Telegram and Discord, progress just maps to partial.
Important limitation
There is still no true token-delta / live terminal stream to chat messages today.
So on Telegram/Discord, “streaming” really means:
- send a preview message
- edit/append it as text arrives
- send final answer at the end
Config examples
Telegram:
channels: {
telegram: {
streaming: "partial"
}
}
Discord:
channels: {
discord: {
streaming: "partial"
}
}
If you want chunked appended output instead of a single edited preview, use:
streaming: "block"
Practical read for ACP
So yes, Telegram can show ongoing progress better than final-only, but it still is not a raw live harness console.
Sorry, short version:
- Yes, Telegram can show ongoing preview updates
- Yes, Discord can too
- No, neither gives you a true live ACP terminal stream
Use:
channels: {
telegram: { streaming: "partial" }
}
or
channels: {
telegram: { streaming: "block" }
}
partial = one message gets edited
block = chunked appended updates
Same idea on Discord.
Show me how to do it for discord
For Discord, set the channel streaming mode to partial or block.
CLI way
openclaw config set channels.discord.streaming partial
openclaw gateway restart
If you want chunked appended updates instead of one edited preview:
openclaw config set channels.discord.streaming block
openclaw gateway restart
Config file shape
{
channels: {
discord: {
streaming: "partial" // or "block"
}
}
}
Which mode to use
partial= one preview message gets edited as output growsblock= output appears in appended chunksprogresson Discord just maps topartial
Important
This gives you Discord preview streaming, not a true live ACP terminal stream.
Whats the default setting