-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
Define durable final fallback delivery semantics across channels #87561
Copy link
Copy link
Open
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.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.maintainerMaintainer-authored PRMaintainer-authored PR
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.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.maintainerMaintainer-authored PRMaintainer-authored PR
Type
Fields
Give feedbackNo fields configured for issues without a type.
Problem
OpenClaw has several user-visible failure modes where an agent turn ends with a sanitized fallback/error message internally, but the user sees silence because the channel delivery layer suppresses, drops, or cannot prove delivery of the final payload.
The current WhatsApp report in #84569 is one concrete example: the embedded runner can produce a safe final
isError: truepayload for an incomplete turn, but the WhatsApp delivery path suppresses it. The same product problem shows up in related channel and recovery issues: final user-visible work exists, or should exist, but delivery status is ambiguous or absent.This should be solved as a core channel contract:
Related issues and PRs
Directly related:
payloads=0and no reply.isErrordelivery.Delivery and receipt semantics:
message_tool_onlysource replies fail because durable send requires reconcile support.Session and recovery surfaces:
payloads=0.Other related silent/lost delivery reports:
Desired contract
Core should define and test these rules:
ReplyPayload.isError === truemeans user-visible error/fallback classification. It must not mean automatic suppression.sent, with platform identity or receiptfailed, with failure stage and errorpartial_failed, if earlier payloads were sent and a later payload failedsuppressed, only when suppression is intentional and has a reasonmessageId: ""must not be treated as successful delivery for visible final text.Implementation plan
Clarify the SDK/channel contract around
isError, durable final text, and visible fallback delivery.Likely surfaces:
src/auto-reply/reply-payload.tssrc/channels/plugins/outbound.types.tssrc/channels/message/types.tssrc/plugin-sdk/channel-outbound.tsTighten core durable delivery semantics.
Likely surfaces:
src/infra/outbound/deliver.tssrc/infra/outbound/deliver-types.tssrc/channels/message/send.tsCore should not let a visible final fallback disappear as a no-op result.
Make final fallback classification explicit enough that channels do not infer policy from
isErroralone.The important distinction is:
Audit bundled channel adapters for
isErrorsuppression or empty-identity delivery results.Known starting points include WhatsApp, Telegram, Slack, Discord, Signal, Feishu, and Matrix.
Revisit
sendTextOnlyErrorPayloads.This should either be removed, narrowed to “adapter needs full payload context,” or guarded so routing through
sendPayloadcannot silently drop final visible fallback text.Add general tests before channel-specific tests.
Core tests should prove:
isError: truetext is delivered on a durable text channelAdd cross-channel conformance coverage.
For channels declaring durable final text support, prove:
Bring channel adapters into compliance.
fix(whatsapp): deliver final error payloads so incomplete-turn errors reach users #84578 can be treated as the immediate WhatsApp compliance patch, but the long-term fix should not be framed around WhatsApp. WhatsApp is one proving case for the shared durable final text contract.
Add observability.
Session/diagnostic state should expose at least:
Non-goals
sendErrorPayloadsfor this behavior. Delivering safe final fallback text should be the product default.isErrorpayload visible; non-final tool/progress/internal payloads may still be hidden.Acceptance proof
This should not be considered production-ready until there is: