openclaw - ✅(Solved) Fix Slack continuation replies can lose thread identity or flatten when routing and send disagree [1 pull requests, 5 comments, 5 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69741Fetched 2026-04-22 07:48:52
View on GitHub
Comments
5
Participants
5
Timeline
13
Reactions
0
Author
Timeline (top)
commented ×5mentioned ×3subscribed ×3closed ×1

Slack continuation replies can lose thread identity, flatten to top-level channel delivery, or duplicate into the wrong place when thread routing and session routing diverge.

This looks like a core Slack/runtime routing bug, not a local workflow helper bug.

Root Cause

  1. routing and actual Slack delivery can disagree about which thread id is authoritative because threadId / replyToId precedence is reversed across layers
  2. a provided parent session key can flatten a newly derived thread-specific route back onto the broader parent session

Fix Action

Fixed

PR fix notes

PR #69752: fix(slack): preserve thread-specific routing

Description (problem / solution / changelog)

Summary

  • prefer threadId over replyToId when Slack outbound delivery sends threaded replies
  • preserve derived thread-scoped session routing when a broader session key is provided
  • add regression coverage for outbound adapter precedence and gateway routing

Testing

  • corepack pnpm vitest run extensions/slack/src/outbound-adapter.test.ts src/gateway/server-methods/send.test.ts

Fixes #69741

Changed files

  • extensions/slack/src/outbound-adapter.test.ts (modified, +23/-0)
  • extensions/slack/src/outbound-adapter.ts (modified, +1/-1)
  • src/gateway/server-methods/send.test.ts (modified, +43/-0)
  • src/gateway/server-methods/send.ts (modified, +8/-1)
RAW_BUFFERClick to expand / collapse

Summary

Slack continuation replies can lose thread identity, flatten to top-level channel delivery, or duplicate into the wrong place when thread routing and session routing diverge.

This looks like a core Slack/runtime routing bug, not a local workflow helper bug.

Evidence

Observed on OpenClaw 2026.4.14 (323493f) during a Slack routing investigation:

  • thread continuation is inferred from tool context via resolveSlackAutoThreadId(...)
  • outbound session routing is thread-sensitive and encodes :thread:<id> into the effective session key
  • actual Slack send computes threadTs as params.replyToId ?? String(params.threadId)
  • route building computes thread identity as params.threadId ?? params.replyToId
  • if a request already carries sessionKey, the server route path can preserve derived route metadata but overwrite sessionKey and baseSessionKey with the provided session key

That creates at least two credible failure modes:

  1. routing and actual Slack delivery can disagree about which thread id is authoritative because threadId / replyToId precedence is reversed across layers
  2. a provided parent session key can flatten a newly derived thread-specific route back onto the broader parent session

Observed symptom class:

  • continuation replies that should stay in-thread can post at channel level
  • mirrored/session-bound followups can attach to the wrong session
  • duplicate or wrong-place delivery can happen when thread-specific routing and actual outbound send target diverge

Current code path clues

Relevant runtime seams:

  • Slack thread inference and outbound send:
    • dist/channel-*.js
    • resolveSlackAutoThreadId(...)
    • resolveSlackOutboundSessionRoute(...)
    • sendSlackOutboundMessage(...)
  • generic message-action normalization:
    • dist/message-action-runner-*.js
    • resolveAndApplyOutboundThreadId(...)
    • prepareOutboundMirrorRoute(...)
  • thread-aware session-key derivation:
    • dist/session-key-*.js
    • resolveThreadSessionKeys(...)
  • gateway route override path:
    • dist/server.impl-*.js

The strongest concrete smells are:

  • threadId ?? replyToId used in routing while replyToId ?? threadId is used in final Slack send
  • derived thread route specificity being collapsed by caller-provided sessionKey

Why this is distinct from other recent issues

This is not the Slack Socket Mode stale-socket problem and not the parent-owned subagent completion-resolution bug.

It also does not look like a local plugin/helper issue. The evidence points to the OpenClaw Slack/runtime continuation path itself.

Proposed direction

  • unify thread-id precedence across route derivation and final Slack send
  • do not let a provided broader session key silently flatten a derived thread-specific route when the outbound route is explicitly thread-bound
  • add regression tests covering:
    • continuation replies in existing Slack threads
    • cases where threadId and replyToId differ or only one is populated
    • cases where a provided parent session key coexists with a newly derived thread route
    • prevention of top-level flattening and wrong-session mirrored delivery

Acceptance criteria

  • a continuation reply that starts from a Slack thread remains bound to that thread through routing and final send
  • routing and final Slack delivery use the same authoritative thread identity
  • provided parent session keys do not collapse explicitly derived thread routes
  • regression tests catch top-level flattening, wrong-session attachment, and duplicate/wrong-place threaded delivery

extent analysis

TL;DR

Unify thread-id precedence across route derivation and final Slack send to prevent thread identity loss and incorrect delivery.

Guidance

  • Review the resolveSlackAutoThreadId and sendSlackOutboundMessage functions to ensure consistent thread-id precedence.
  • Modify the resolveAndApplyOutboundThreadId function to prioritize threadId over replyToId for consistency with the final Slack send.
  • Update the resolveThreadSessionKeys function to prevent a provided parent session key from overwriting a derived thread-specific route.
  • Implement regression tests to cover various scenarios, including continuation replies, differing threadId and replyToId values, and coexisting parent session keys.

Example

// Example of unifying thread-id precedence
function resolveAndApplyOutboundThreadId(params) {
  const threadId = params.threadId || params.replyToId;
  // ...
}

function sendSlackOutboundMessage(params) {
  const threadTs = params.threadId || params.replyToId;
  // ...
}

Notes

The proposed solution focuses on unifying thread-id precedence and preventing session key overwriting. However, additional testing and verification are necessary to ensure the fix covers all scenarios and edge cases.

Recommendation

Apply the proposed workaround by unifying thread-id precedence and modifying the session key derivation to prevent overwriting. This should help prevent thread identity loss and incorrect delivery, and the added regression tests will help catch any remaining issues.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Slack continuation replies can lose thread identity or flatten when routing and send disagree [1 pull requests, 5 comments, 5 participants]