You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
When an assistant response contains text followed by a tool call in the same turn (stopReason: "toolUse"), the text portion is not delivered to the Signal channel — only a subsequent, separate turn that ends cleanly (stopReason: "stop") actually reaches the user. The dropped text is fully present in the session transcript/JSONL as if it had been sent, with no indication to the agent or any log-visible error that delivery failed. This caused a real data-integrity incident: a required user-confirmation question was never delivered, and the agent proceeded as if a later, unrelated reply had confirmed it.
This appears closely related to #9983 ("Minimax: Text before tool calls not sent to chat"), but that report attributes the cause specifically to Minimax's non-streaming text+tool_call bundling behavior, implying Claude/Sonnet emits these as separate streamed events and is unaffected. This report shows the same symptom occurring with Anthropic claude-sonnet-5 on the Signal channel, so the issue is not Minimax-specific.
Steps to reproduce
Configure an agent on the Signal channel with a workflow that asks the user a confirmation question and then, in the same response, calls a tool (e.g., checking whether a file exists, querying a database) before continuing.
Send a message that triggers this flow.
Observe the assistant's response in the session transcript (agents//sessions/.jsonl): the response contains a text block asking the confirmation question, immediately followed by a toolCall block, with "stopReason":"toolUse".
Compare against what actually arrives on the Signal client. The text portion is never delivered — only a later, subsequent assistant message (one that ends with "stopReason":"stop" and has no attached tool call) is received.
The user, having never seen the question, replies to whatever was actually delivered. The agent — relying on its own transcript, which shows the question as sent — treats the reply as an answer to the undelivered question.
Expected behavior
Text content generated in the same turn as a tool call should either:
Be delivered to the channel before or alongside the tool call executing (matching what the session transcript records as having happened), or
If intentionally suppressed by design (per the discussion in Expose stopReason in message_sending plugin hook metadata #66235), the agent should be made aware — via a system-level signal, injected note, or the tool result itself — that its preceding text was not delivered, so it does not proceed as though the user received and could have responded to it.
Actual behavior
The text is recorded as sent in the transcript, is invisible to the end user, and the agent has no way to detect the discrepancy without a manual line-by-line comparison against the user's actual client.
Model registered manually under models.providers.anthropic.models[] in openclaw.json, since OpenClaw's built-in catalog did not yet include claude-sonnet-5 at the time of setup.
Relevant config lives in openclaw.json under models.providers.anthropic.
Logs
Screenshots, recordings, and evidence
Raw transcript excerpt (session file, redacted only where noted) — the assistant message containing the confirmation question, ending in toolUse:
{
"type": "message",
"id": "ffff22e6",
"message": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "...Also confirming: property is [PROPERTY_ADDRESS], personal card, owed to [PERSON_NAME] — same as your standing instruction, correct? And I still need to move the staged file to shared storage before logging — doing that now."
},
{
"type": "toolCall",
"id": "toolu_[REDACTED_TOOL_CALL_ID]",
"name": "exec",
"arguments": { "command": "ls -la media/inbound/[REDACTED_FILENAME].jpg 2>&1" }
}
],
"api": "anthropic-messages",
"provider": "anthropic",
"model": "claude-sonnet-5",
"stopReason": "toolUse"
}
}
The only message that actually reached the Signal client at this point in the conversation (confirmed via screenshot of the Signal app) was a separate, later assistant turn:
{
"type": "message",
"id": "45b0f614",
"message": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "File confirmed staged in my workspace — holding the move until you confirm categorization and property/payment details above, then I'll move it and log everything in one pass."
}
],
"stopReason": "stop"
}
}
Note this second message references "details above" (i.e., the property/payment question) as if the user had already seen it — but the user's Signal client never received the message containing those details at all. Only this second, self-contained "stop" turn was delivered.
(Message/session IDs shown above are internal identifiers only; the property address, payment-recipient name, and filename UUID in the original transcript have been replaced with placeholders for privacy.)
Impact and severity
Affected users/systems/channels: Confirmed on the Signal channel with anthropic/claude-sonnet-5 (non-streaming), OpenClaw 2026.6.11, self-hosted deployment. Whether this affects other channels or models is NOT_ENOUGH_INFO — only Signal/Sonnet was directly observed.
Severity: Data risk. The dropped message was a required user-confirmation question (property/payment details) for a financial record-keeping workflow. Because the drop is silent and undetectable from the agent's own transcript, the agent proceeded to log a database record based on an unrelated later reply, treating it as if it had answered the undelivered question. The record was written with unconfirmed data as a direct result.
Frequency: NOT_ENOUGH_INFO on general frequency (always/intermittent/edge case) — this was observed and confirmed once in our deployment via direct transcript-to-Signal-client comparison. We have not run repeated trials to determine how often it recurs under the same conditions (text + tool call in the same turn).
Consequence: A financial record (a retail receipt, $224.37) was logged with owner-confirmed property and payment/reimbursement fields that the owner had never actually seen or approved, because the confirmation question that should have preceded logging was silently dropped. The incorrect data was caught and corrected only through manual comparison of the raw session transcript against the user's actual Signal message history — there was no automated way to detect the discrepancy.
Additional information
Flush/deliver assistant text to the channel as soon as it's generated, before a subsequent tool call executes in the same turn.
At minimum, surface the drop to the agent so it can be instructed to re-send.
Document this behavior explicitly in the Signal/Messages docs.
Related Issues #9983 — same symptom (text before tool call dropped from chat), attributed to Minimax-specific streaming behavior. This report shows the same symptom on Anthropic/Sonnet via Signal, suggesting the root cause may be broader than provider-specific streaming differences, or that non-streaming delivery paths generally have this gap regardless of provider. #66235 — feature request to explicitly suppress stopReason: toolUse text via a plugin hook, describing this drop as consistent/expected in non-streaming mode. If this is intentional, it should be documented clearly and the agent-side blind spot described above should be addressed regardless. #25592 — related but distinct: concerns intermediate text leaking to channels when it shouldn't; this report concerns the opposite — text that should reach the user being dropped. #76915 (closed) — related but distinct: that issue concerns assistant text generated AFTER a message-tool call completes (trailing commentary dropped from Telegram), whereas this report concerns text generated BEFORE a tool call in the same turn (stopReason: toolUse), across arbitrary tool types (not just the message tool), on Signal rather than Telegram.
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
When an assistant response contains text followed by a tool call in the same turn (stopReason: "toolUse"), the text portion is not delivered to the Signal channel — only a subsequent, separate turn that ends cleanly (stopReason: "stop") actually reaches the user. The dropped text is fully present in the session transcript/JSONL as if it had been sent, with no indication to the agent or any log-visible error that delivery failed. This caused a real data-integrity incident: a required user-confirmation question was never delivered, and the agent proceeded as if a later, unrelated reply had confirmed it.
This appears closely related to #9983 ("Minimax: Text before tool calls not sent to chat"), but that report attributes the cause specifically to Minimax's non-streaming text+tool_call bundling behavior, implying Claude/Sonnet emits these as separate streamed events and is unaffected. This report shows the same symptom occurring with Anthropic claude-sonnet-5 on the Signal channel, so the issue is not Minimax-specific.
Steps to reproduce
Expected behavior
Text content generated in the same turn as a tool call should either:
Actual behavior
The text is recorded as sent in the transcript, is invisible to the end user, and the agent has no way to detect the discrepancy without a manual line-by-line comparison against the user's actual client.
OpenClaw version
2026.6.11 (e085fa1)
Operating system
Ubuntu Server 26.04
Install method
npm
Model
anthropic/claude-sonnet-5
Provider / routing chain
openclaw -> anthropic (direct)
Additional provider/model setup details
Direct route is openclaw -> api.anthropic.com (anthropic-messages API), no proxy, gateway, or router in between — confirmed via gateway logs showing requests going straight to https://api.anthropic.com/v1/messages.
Model registered manually under models.providers.anthropic.models[] in openclaw.json, since OpenClaw's built-in catalog did not yet include claude-sonnet-5 at the time of setup.
Relevant config lives in openclaw.json under models.providers.anthropic.
Logs
Screenshots, recordings, and evidence
Raw transcript excerpt (session file, redacted only where noted) — the assistant message containing the confirmation question, ending in toolUse:
{
"type": "message",
"id": "ffff22e6",
"message": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "...Also confirming: property is [PROPERTY_ADDRESS], personal card, owed to [PERSON_NAME] — same as your standing instruction, correct? And I still need to move the staged file to shared storage before logging — doing that now."
},
{
"type": "toolCall",
"id": "toolu_[REDACTED_TOOL_CALL_ID]",
"name": "exec",
"arguments": { "command": "ls -la media/inbound/[REDACTED_FILENAME].jpg 2>&1" }
}
],
"api": "anthropic-messages",
"provider": "anthropic",
"model": "claude-sonnet-5",
"stopReason": "toolUse"
}
}
The only message that actually reached the Signal client at this point in the conversation (confirmed via screenshot of the Signal app) was a separate, later assistant turn:
{
"type": "message",
"id": "45b0f614",
"message": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "File confirmed staged in my workspace — holding the move until you confirm categorization and property/payment details above, then I'll move it and log everything in one pass."
}
],
"stopReason": "stop"
}
}
Note this second message references "details above" (i.e., the property/payment question) as if the user had already seen it — but the user's Signal client never received the message containing those details at all. Only this second, self-contained "stop" turn was delivered.
(Message/session IDs shown above are internal identifiers only; the property address, payment-recipient name, and filename UUID in the original transcript have been replaced with placeholders for privacy.)
Impact and severity
Affected users/systems/channels: Confirmed on the Signal channel with anthropic/claude-sonnet-5 (non-streaming), OpenClaw 2026.6.11, self-hosted deployment. Whether this affects other channels or models is NOT_ENOUGH_INFO — only Signal/Sonnet was directly observed.
Severity: Data risk. The dropped message was a required user-confirmation question (property/payment details) for a financial record-keeping workflow. Because the drop is silent and undetectable from the agent's own transcript, the agent proceeded to log a database record based on an unrelated later reply, treating it as if it had answered the undelivered question. The record was written with unconfirmed data as a direct result.
Frequency: NOT_ENOUGH_INFO on general frequency (always/intermittent/edge case) — this was observed and confirmed once in our deployment via direct transcript-to-Signal-client comparison. We have not run repeated trials to determine how often it recurs under the same conditions (text + tool call in the same turn).
Consequence: A financial record (a retail receipt, $224.37) was logged with owner-confirmed property and payment/reimbursement fields that the owner had never actually seen or approved, because the confirmation question that should have preceded logging was silently dropped. The incorrect data was caught and corrected only through manual comparison of the raw session transcript against the user's actual Signal message history — there was no automated way to detect the discrepancy.
Additional information
Related Issues
#9983 — same symptom (text before tool call dropped from chat), attributed to Minimax-specific streaming behavior. This report shows the same symptom on Anthropic/Sonnet via Signal, suggesting the root cause may be broader than provider-specific streaming differences, or that non-streaming delivery paths generally have this gap regardless of provider.
#66235 — feature request to explicitly suppress stopReason: toolUse text via a plugin hook, describing this drop as consistent/expected in non-streaming mode. If this is intentional, it should be documented clearly and the agent-side blind spot described above should be addressed regardless.
#25592 — related but distinct: concerns intermediate text leaking to channels when it shouldn't; this report concerns the opposite — text that should reach the user being dropped.
#76915 (closed) — related but distinct: that issue concerns assistant text generated AFTER a message-tool call completes (trailing commentary dropped from Telegram), whereas this report concerns text generated BEFORE a tool call in the same turn (stopReason: toolUse), across arbitrary tool types (not just the message tool), on Signal rather than Telegram.