[Bug]: Stalled direct chat model call surfaces "LLM request failed" instead of auto-resetting/retrying the wedged session
Bug type
Behavior bug (incorrect output/state without crash)
Summary
A Telegram direct chat session with a large/previously compacted transcript wedged during the assistant/model stage; OpenClaw detected active_work_without_progress, aborted the embedded run after ~383s, and delivered a generic user-visible LLM request failed. instead of automatically resetting the hot session state and retrying from preserved durable memory.
This appears related to, but not fully covered by, closed issue #20910 ("Auto-reset session when all models time out (session bloat death spiral)"). In this incident the provider request did not behave like a normal timeout/fallback case: the Responses stream ended after ~383s with zero events/content blocks and Request was aborted, OpenClaw classified the failure as unclassified, no fallback was configured/used, and the direct chat required a manual sessions.reset to recover.
Impact and severity
- Affected surface: Telegram direct bot account routed to an OpenClaw agent.
- Severity: high for chat use. The bot is reachable and receives user messages, but the user sees repeated
LLM request failed. instead of the tutoring/assistant reply.
- Frequency in this session: occurred repeatedly for the same direct chat until manual session reset.
- Practical consequence: the human user kept messaging the bot, saw generic failures, and missed the intended response until an operator manually diagnosed and reset the exact session key.
- Risk: any long-lived channel session with substantial transcript/compaction history can enter this "gateway and channel are healthy, hot session is wedged" state. The current recovery path correctly detects and aborts, but does not perform the user-preserving automatic recovery step.
Environment
- OpenClaw version:
OpenClaw 2026.6.1 (2e08f0f)
- Update status: stable channel, no registry/git update available at time of incident.
- Install method: npm/Homebrew-managed package, LaunchAgent service.
- Package root:
/opt/homebrew/lib/node_modules/openclaw
- CLI entrypoint:
/opt/homebrew/bin/openclaw
- Service: LaunchAgent
ai.openclaw.gateway
- Service command:
/opt/homebrew/opt/node/bin/node
/opt/homebrew/lib/node_modules/openclaw/dist/index.js
gateway
--port
18789
- OS: macOS 26.3, build
25D125
- Kernel: Darwin 25.3.0 arm64
- Gateway bind:
0.0.0.0:18789
- Effective agent provider/model:
codex-lb/gpt-5.5
- API path logged by OpenClaw:
openai-responses
- Channel: Telegram, polling mode
Steps to reproduce
This is not yet a minimal synthetic repro, but this is the end-to-end incident path observed on a real installed Gateway:
- Run OpenClaw
2026.6.1 as the installed LaunchAgent gateway.
- Configure a Telegram account and route a direct chat to an agent using
codex-lb/gpt-5.5.
- Let that direct session accumulate a large transcript and multiple compaction checkpoints.
- The affected entry had
compactionCount: 23 after reset.
- The reset output showed a prior compaction checkpoint preserving a long Russian review session summary.
- Receive a normal Telegram direct user message in that session.
- Observe that OpenClaw routes it correctly and starts an embedded agent/model run.
- The model call produces no useful content for several minutes.
- OpenClaw's stalled-session recovery aborts the embedded run.
- OpenClaw delivers generic text
LLM request failed. to the Telegram user.
- Further messages in the same direct chat continue failing/stalling until an operator manually resets the exact session key:
openclaw gateway call sessions.reset \
--params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \
--json \
--timeout 60000
- After reset, a non-delivered probe against the exact same session key succeeds in ~2.3s, and a delivered Telegram reply succeeds in ~3.3s.
Expected behavior
When a long-lived channel session is classified as stalled due to active_work_without_progress and recovery aborts the embedded run:
- OpenClaw should recognize the failure as a wedged hot session / compaction or transcript state problem when the gateway, channel, routing, and provider are otherwise reachable.
- It should preserve durable agent memory/checkpoints, reset the active session file/key to a fresh safe state, and retry the user's turn once.
- It should only surface a user-visible failure after the reset+retry also fails.
- The user-facing message should avoid a raw/generic
LLM request failed. when OpenClaw has enough context to perform a known recovery.
- Operator diagnostics should clearly say something like
session reset/retry attempted after stalled model call and include whether the retry succeeded.
Actual behavior
OpenClaw did detect the session stall and abort the embedded run, but then surfaced the failure directly to the user. No automatic reset/retry was attempted.
The manual recovery that made the session healthy again was exactly:
openclaw gateway call sessions.reset \
--params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \
--json \
--timeout 60000
After that, the same direct session key responded normally and delivery succeeded.
Evidence
Gateway and channel were healthy
At diagnosis time the Gateway was up, the installed service was running, RPC worked, and the port listener existed:
openclaw --version
# OpenClaw 2026.6.1 (2e08f0f)
openclaw update status --json
# stable channel, latestVersion 2026.6.1, no update available
openclaw gateway status --require-rpc --json
# cli.version: 2026.6.1
# service.loaded: true
# service.runtime.status: running
# service.runtime.state: active
# gateway.bindHost: 0.0.0.0
# gateway.port: 18789
# rpc.ok: true
# rpc.capability: admin_capable
lsof -nP -iTCP:18789 -sTCP:LISTEN
# node ... TCP *:18789 (LISTEN)
curl -fsS --max-time 5 http://127.0.0.1:18789/health
# {"ok":true,"status":"live"}
Telegram was connected and polling. The affected account showed running:true, connected:true, lastError:null, and recent inbound/outbound activity.
Stalled-session detection occurred
OpenClaw diagnostic events showed an active model call making no progress:
session.stalled
outcome=processing
reason=active_work_without_progress
queueDepth=1
activeWorkKind=model_call
The log line for the affected direct session:
stalled session:
sessionKey=agent:<agent-id>:telegram:direct:<redacted-chat-id>
state=processing
age=353s
queueDepth=1
reason=active_work_without_progress
classification=stalled_agent_run
activeWorkKind=model_call
lastProgress=model_call:stream_progress
lastProgressAge=353s
recovery=none
Then:
stalled session:
state=processing
age=383s
reason=active_work_without_progress
classification=stalled_agent_run
activeWorkKind=model_call
lastProgress=model_call:stream_progress
lastProgressAge=383s
recovery=checking
Provider stream ended with no usable content, then abort was surfaced
[responses] stream_done
provider=codex-lb
api=openai-responses
model=gpt-5.5
elapsedMs=382908
events=0
types=
stopReason=stop
contentBlocks=0
Immediately after:
[responses] error
provider=codex-lb
api=openai-responses
model=gpt-5.5
name=Error
status=undefined
code=undefined
type=undefined
message=Request was aborted
Then:
stuck session recovery:
sessionKey=agent:<agent-id>:telegram:direct:<redacted-chat-id>
age=383s
action=abort_embedded_run
aborted=true
drained=true
released=0
Failover decision:
embedded_run_failover_decision
stage=assistant
decision=surface_error
provider=codex-lb
model=gpt-5.5
sourceProvider=codex-lb
sourceModel=gpt-5.5
fallbackConfigured=false
timedOut=false
aborted=true
rawErrorPreview="Request was aborted"
providerRuntimeFailureKind=unclassified
OpenClaw then delivered the failure text successfully over Telegram:
telegram outbound send ok
accountId=<telegram-account>
chatId=<redacted-chat-id>
operation=sendMessage
deliveryKind=text
chunkCount=1
message dispatch completed
outcome=completed
duration=385848ms
The Telegram user-visible message was:
Manual reset fixed the exact session
Manual reset result:
{
"ok": true,
"key": "agent:<agent-id>:telegram:direct:<redacted-chat-id>",
"entry": {
"sessionId": "975ec9f4-b6fd-44a7-8171-4308c2a91005",
"sessionFile": "/Users/<user>/.openclaw/agents/<agent-id>/sessions/2026-06-03T14-34-47-669Z_975ec9f4-b6fd-44a7-8171-4308c2a91005.jsonl",
"systemSent": false,
"abortedLastRun": false,
"chatType": "direct",
"model": "gpt-5.5",
"modelProvider": "codex-lb",
"compactionCount": 23,
"origin": {
"provider": "telegram",
"surface": "telegram",
"chatType": "direct",
"accountId": "<telegram-account>"
},
"deliveryContext": {
"channel": "telegram",
"accountId": "<telegram-account>"
}
}
}
After reset, a non-delivered probe against the exact direct session key succeeded:
openclaw agent \
--agent <agent-id> \
--session-key agent:<agent-id>:telegram:direct:<redacted-chat-id> \
--message 'Diagnostic only after reset. Reply exactly: TINA_SESSION_OK' \
--json \
--timeout 60
Result:
{
"status": "ok",
"summary": "completed",
"result": {
"payloads": [
{
"text": "TINA_SESSION_OK"
}
],
"meta": {
"durationMs": 2329,
"agentMeta": {
"provider": "codex-lb",
"model": "gpt-5.5",
"usage": {
"input": 7239,
"output": 8,
"total": 7247
}
},
"executionTrace": {
"winnerProvider": "codex-lb",
"winnerModel": "gpt-5.5",
"attempts": [
{
"provider": "codex-lb",
"model": "gpt-5.5",
"result": "success",
"stage": "assistant"
}
],
"fallbackUsed": false,
"runner": "embedded"
}
}
}
}
A delivered reply then succeeded:
{
"status": "ok",
"summary": "completed",
"result": {
"deliverySucceeded": true,
"deliveryStatus": {
"requested": true,
"attempted": true,
"status": "sent",
"succeeded": true,
"resultCount": 1
}
}
}
Why this looks like an OpenClaw bug
This was not a Telegram availability failure:
- Telegram channel/account was running and connected.
- Inbound messages were received.
- Routing matched the intended agent.
- Outbound Telegram delivery worked, including the bad
LLM request failed. message and the later successful reply.
This was not a Gateway-down failure:
- Gateway health returned live.
- LaunchAgent service was running.
- RPC was OK.
- Port
18789 was listening.
This was not a permanent provider outage:
- A fresh diagnostic session using the same agent/provider/model returned
OPENCLAW_OK in ~1.9s.
- The exact affected direct session returned
TINA_SESSION_OK in ~2.3s after sessions.reset.
- A delivered reply using the exact affected direct session succeeded in ~3.3s after reset.
The defect is the recovery policy between:
- Detecting a stalled direct session,
- Aborting the embedded run,
- Classifying the runtime failure,
- Choosing
surface_error,
- Sending
LLM request failed. to the human,
- Not performing the same
sessions.reset recovery that immediately fixed the session when run manually.
Proposed fix
Add an automatic safe recovery path for channel-backed direct sessions when all of the following are true:
- session is
processing;
- reason/classification is
active_work_without_progress / stalled_agent_run;
- active work is
model_call or embedded assistant run;
- recovery aborts the run successfully;
- provider result is aborted/unclassified/no-content, not a user/tool validation error;
- the channel account is healthy enough to deliver;
- the session has compaction history or active transcript size triggers indicating a likely hot-session/transcript wedge.
Suggested behavior:
- Mark the failed run as aborted.
- Preserve durable memory/checkpoints.
- Reset the hot session entry using the same supported mechanism as
sessions.reset.
- Retry the user's original turn exactly once.
- If retry succeeds, deliver the real reply and log
auto_session_reset_retry_succeeded.
- If retry fails, surface a clearer message and log
auto_session_reset_retry_failed with the failed reason.
Guardrails:
- Do not reset indefinitely. One auto-reset retry per incoming message/session failure is enough.
- Do not reset on tool permission/validation errors or explicit provider auth errors.
- Keep the original inbound message id/trace linked to the retry for operator audit.
- Make the diagnostic/event stream show that an auto reset was attempted.
Temporary workaround
Manual operator reset of the affected direct session:
openclaw gateway call sessions.reset \
--params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \
--json \
--timeout 60000
Then verify without delivering:
openclaw agent \
--agent <agent-id> \
--session-key agent:<agent-id>:telegram:direct:<redacted-chat-id> \
--message 'Diagnostic only after reset. Reply exactly: OK' \
--json \
--timeout 60
Additional notes
- The first attempted
sessions.reset with a descriptive reason failed schema validation because reason appears to require a strict constant. That is probably fine, but a clearer CLI error or accepted enum in help would make operator recovery easier.
- The installed recovery runbook expected this exact manual reset shape for "large transcript failures can show up as preflight compaction stuck near maxActiveTranscriptBytes"; this incident confirms the runbook but suggests Gateway should perform the safe path automatically for channel sessions.
- Public issue is redacted: chat id, account names, local username, and human names have been omitted or generalized.
[Bug]: Stalled direct chat model call surfaces "LLM request failed" instead of auto-resetting/retrying the wedged session
Bug type
Behavior bug (incorrect output/state without crash)
Summary
A Telegram direct chat session with a large/previously compacted transcript wedged during the assistant/model stage; OpenClaw detected
active_work_without_progress, aborted the embedded run after ~383s, and delivered a generic user-visibleLLM request failed.instead of automatically resetting the hot session state and retrying from preserved durable memory.This appears related to, but not fully covered by, closed issue #20910 ("Auto-reset session when all models time out (session bloat death spiral)"). In this incident the provider request did not behave like a normal timeout/fallback case: the Responses stream ended after ~383s with zero events/content blocks and
Request was aborted, OpenClaw classified the failure asunclassified, no fallback was configured/used, and the direct chat required a manualsessions.resetto recover.Impact and severity
LLM request failed.instead of the tutoring/assistant reply.Environment
OpenClaw 2026.6.1 (2e08f0f)/opt/homebrew/lib/node_modules/openclaw/opt/homebrew/bin/openclawai.openclaw.gateway/opt/homebrew/opt/node/bin/node/opt/homebrew/lib/node_modules/openclaw/dist/index.jsgateway--port1878925D1250.0.0.0:18789codex-lb/gpt-5.5openai-responsesSteps to reproduce
This is not yet a minimal synthetic repro, but this is the end-to-end incident path observed on a real installed Gateway:
2026.6.1as the installed LaunchAgent gateway.codex-lb/gpt-5.5.compactionCount: 23after reset.LLM request failed.to the Telegram user.openclaw gateway call sessions.reset \ --params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \ --json \ --timeout 60000Expected behavior
When a long-lived channel session is classified as stalled due to
active_work_without_progressand recovery aborts the embedded run:LLM request failed.when OpenClaw has enough context to perform a known recovery.session reset/retry attempted after stalled model calland include whether the retry succeeded.Actual behavior
OpenClaw did detect the session stall and abort the embedded run, but then surfaced the failure directly to the user. No automatic reset/retry was attempted.
The manual recovery that made the session healthy again was exactly:
openclaw gateway call sessions.reset \ --params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \ --json \ --timeout 60000After that, the same direct session key responded normally and delivery succeeded.
Evidence
Gateway and channel were healthy
At diagnosis time the Gateway was up, the installed service was running, RPC worked, and the port listener existed:
Telegram was connected and polling. The affected account showed
running:true,connected:true,lastError:null, and recent inbound/outbound activity.Stalled-session detection occurred
OpenClaw diagnostic events showed an active model call making no progress:
The log line for the affected direct session:
Then:
Provider stream ended with no usable content, then abort was surfaced
Immediately after:
Then:
Failover decision:
OpenClaw then delivered the failure text successfully over Telegram:
The Telegram user-visible message was:
Manual reset fixed the exact session
Manual reset result:
{ "ok": true, "key": "agent:<agent-id>:telegram:direct:<redacted-chat-id>", "entry": { "sessionId": "975ec9f4-b6fd-44a7-8171-4308c2a91005", "sessionFile": "/Users/<user>/.openclaw/agents/<agent-id>/sessions/2026-06-03T14-34-47-669Z_975ec9f4-b6fd-44a7-8171-4308c2a91005.jsonl", "systemSent": false, "abortedLastRun": false, "chatType": "direct", "model": "gpt-5.5", "modelProvider": "codex-lb", "compactionCount": 23, "origin": { "provider": "telegram", "surface": "telegram", "chatType": "direct", "accountId": "<telegram-account>" }, "deliveryContext": { "channel": "telegram", "accountId": "<telegram-account>" } } }After reset, a non-delivered probe against the exact direct session key succeeded:
Result:
{ "status": "ok", "summary": "completed", "result": { "payloads": [ { "text": "TINA_SESSION_OK" } ], "meta": { "durationMs": 2329, "agentMeta": { "provider": "codex-lb", "model": "gpt-5.5", "usage": { "input": 7239, "output": 8, "total": 7247 } }, "executionTrace": { "winnerProvider": "codex-lb", "winnerModel": "gpt-5.5", "attempts": [ { "provider": "codex-lb", "model": "gpt-5.5", "result": "success", "stage": "assistant" } ], "fallbackUsed": false, "runner": "embedded" } } } }A delivered reply then succeeded:
{ "status": "ok", "summary": "completed", "result": { "deliverySucceeded": true, "deliveryStatus": { "requested": true, "attempted": true, "status": "sent", "succeeded": true, "resultCount": 1 } } }Why this looks like an OpenClaw bug
This was not a Telegram availability failure:
LLM request failed.message and the later successful reply.This was not a Gateway-down failure:
18789was listening.This was not a permanent provider outage:
OPENCLAW_OKin ~1.9s.TINA_SESSION_OKin ~2.3s aftersessions.reset.The defect is the recovery policy between:
surface_error,LLM request failed.to the human,sessions.resetrecovery that immediately fixed the session when run manually.Proposed fix
Add an automatic safe recovery path for channel-backed direct sessions when all of the following are true:
processing;active_work_without_progress/stalled_agent_run;model_callor embedded assistant run;Suggested behavior:
sessions.reset.auto_session_reset_retry_succeeded.auto_session_reset_retry_failedwith the failed reason.Guardrails:
Temporary workaround
Manual operator reset of the affected direct session:
openclaw gateway call sessions.reset \ --params '{"key":"agent:<agent-id>:telegram:direct:<redacted-chat-id>","reason":"reset"}' \ --json \ --timeout 60000Then verify without delivering:
Additional notes
sessions.resetwith a descriptive reason failed schema validation becausereasonappears to require a strict constant. That is probably fine, but a clearer CLI error or accepted enum in help would make operator recovery easier.