-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
Agent's final agent_message stranded when LLM forgets to call configured delivery tool (no fallback delivery from task_complete) #85714
Copy link
Copy link
Closed
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Summary
When an OpenClaw agent that delivers via
tools.message(e.g. the bundledsystem-architectagent) occasionally forgets to invoke the message tool on its final turn and instead emits the response as a plainagent_message(not the conventional"NO_REPLY"sentinel), the response is silently stranded in the Codex rollout JSONL and never reaches the originating channel. From the user's perspective the bot looks unresponsive even thoughtask_completefired normally; from the gateway's perspective there is no error to surface, just no outbound.There is no fallback that takes the
task_complete.last_agent_messageand routes it to the inbound channel when the model has failed to call the configured delivery tool.Environment
2026.5.20(/opt/homebrew/lib/node_modules/openclaw)0.130.0(/opt/homebrew/lib/node_modules/@openai/codex)system-architect(codex-app-server backend, modelopenai/gpt-5.5)@RMHomeSystemArchitect_bot, direct chatRepro (observed in production, 2026-05-23 20:21-20:22 local)
This agent's system prompt establishes a strict delivery contract:
tools.message({action:"send", message:"..."})exactly once.agent_message: "NO_REPLY"as a sentinel so the orchestrator knows the work is done and does not re-deliver.The contract held for the prior 7 turns of the same session. Sequence of those turns (per the codex rollout JSONL
~/.openclaw/agents/system-architect/agent/codex-home/sessions/<date>/rollout-*.jsonl):tools.messageexecsagent_messagecountagent_messagecontent2026-05-23 20:14:51"NO_REPLY"2026-05-23 20:17:49"NO_REPLY"2026-05-23 20:18:09"NO_REPLY"2026-05-23 20:19:19"NO_REPLY"2026-05-23 20:19:21"NO_REPLY"2026-05-23 20:20:30"NO_REPLY"2026-05-23 20:21:35NO_REPLYsentinelThe final turn fired
task_complete(turn_id 019e54c8-ad57-7d50-bb70-e9148e09f514) withlast_agent_messageset to the entire 3,738-char reply. The model simply omitted thetools.messagecall this once.Gateway-side log over the same window (
/tmp/openclaw/openclaw-<date>.log) shows only:Inbound message telegram:6689123501 -> @RMHomeSystemArchitect_bot (direct, 42 chars)at20:21:35.705using external OAuth credential after refresh failureat20:21:37.596No outbound, no stall warning, no recovery — just nothing. User waited 7+ minutes thinking the bot was stuck.
Why this matters
gpt-5.5) demonstrably forget multi-step delivery contracts after long sessions (token-cached prefix → drift). The 7-turn-of-7 success rate before this turn shows the model does know the rule, it just occasionally lapses.agent_messageand re-send viaopenclaw message send.Suggested fix shape
In the codex-app-server bridge / agent run handler, on
task_complete:last_agent_message(already exposed in thetask_completeevent payload)."NO_REPLY") AND notools.message/equivalent outbound has been delivered during this turn → auto-deliverlast_agent_messageto the originating channel as a fallback.WARNlikeagent failed to invoke configured delivery tool; auto-delivering last_agent_message as fallbackso operators can see this happened.This makes the failure mode self-healing instead of silently message-lost.
If the sentinel is agent-specific (it is, for
system-architect), the agent config could exposeagents.list[].deliveryContract: { sentinel: "NO_REPLY" }so the bridge knows what to compare against. Default to "any non-empty final agent_message that wasn't already sent via tools.message".Workaround (current)
Operator manually pulls the stranded
agent_messagefrom the codex rollout JSONL:Not a path a normal user can be expected to discover.
Related
turn/startedsilent hang — different layer: agent doesn't even start a turn there), #83950 (telegram polling stall — inbound side), #85224 (gateway respawn — supervisor layer).