Skip to content

Slack message_tool_only source replies fail because durable send requires reconcileUnknownSend #84078

@tianxiaochannel-oss88

Description

@tianxiaochannel-oss88

Summary

Slack source replies can be forced through the message tool via sourceReplyDeliveryMode: "message_tool_only" (for example for Slack group/channel visible replies when configured that way). In that path, message(action="send") currently performs a required durable-send preflight that unconditionally requires reconcileUnknownSend.

The Slack adapter does not appear to expose reconcileUnknownSend, so the send is rejected before any fallback/best-effort delivery can happen:

Required durable message send is unsupported for slack: missing reconcileUnknownSend

This turns a safe source-reply delivery policy into a visible reply failure for Slack.

Environment

  • OpenClaw package: openclaw 2026.5.18
  • Runtime: macOS Darwin 25.5.0 arm64
  • Node: v24.15.0
  • Provider/channel: Slack channel / group chat thread
  • Config shape involved: Slack group/channel visible source replies routed through the message tool

Evidence from installed package

source-reply-delivery-mode-* can choose message_tool_only for group/channel chats when visible replies are configured as message_tool:

if (chatType === "group" || chatType === "channel") mode =
  (params.cfg.messages?.groupChat?.visibleReplies ?? params.cfg.messages?.visibleReplies) === "message_tool"
    ? "message_tool_only"
    : "automatic";

dist/message-*.js then derives required message-send capabilities with reconcileUnknownSend: true unconditionally:

function deriveRequiredMessageSendCapabilities(params) {
  const requirements = { reconcileUnknownSend: true };
  for (const payload of params.payloads) mergeDurableRequirements(requirements, deriveDurableFinalDeliveryRequirements({
    payload,
    replyToId: params.replyToId,
    threadId: params.threadId,
    silent: params.silent,
    payloadTransport: payloadRequiresDurablePayloadTransport(payload),
    batch: params.payloads.length > 1,
    reconcileUnknownSend: true
  }));
  return requirements;
}

When Slack cannot satisfy that capability, core throws:

throw new Error(`Required durable message send is unsupported for ${params.channel}: ${suffix}`);

The plugin SDK docs say best-effort final delivery does not require reconcileUnknownSend, but required durable final delivery does:

Best-effort final delivery does not require `reconcileUnknownSend` ...
Required durable final delivery must explicitly require `reconcileUnknownSend`.

Observed behavior

In a Slack channel/thread, a visible assistant reply that must use the message tool fails with:

Required durable message send is unsupported for slack: missing reconcileUnknownSend

Using bestEffort: true avoids this particular preflight failure and allows Slack delivery, but the source-reply contract/runtime hint does not make that automatic for the assistant. The model/tool path can therefore be instructed to send via message, while the default durable send path is impossible for Slack.

Expected behavior

One of these should happen:

  1. Slack implements/exposes reconcileUnknownSend, so required durable message sends are supported; or
  2. Slack source replies in message_tool_only mode automatically degrade to best-effort when required durability is unavailable, preserving visible delivery semantics; or
  3. Core/tool instructions make the required bestEffort: true fallback explicit for Slack adapters without reconciliation.

Actual behavior

The send is rejected by durable capability preflight, and the source reply is not posted unless the agent manually retries with bestEffort: true.

Impact

  • Slack channel/group source replies can silently fail or be blocked when the safe message_tool_only delivery policy is enabled.
  • The user sees no visible assistant reply even though the assistant may have completed the turn.
  • Agents are pushed into manual retry/fallback behavior, which is error-prone and can interact badly with duplicate/unknown-send handling.

Related issues

Private Slack channel content is redacted; I can provide additional local session metadata if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper 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.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions