openclaw - ✅(Solved) Fix Slack: internal replyToId can override valid thread anchor and leak replies to channel root [1 pull requests, 1 comments, 2 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#68790Fetched 2026-04-19 15:07:27
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
0
Timeline (top)
commented ×1

Slack replies can leak to the channel root when [[reply_to_current]] resolves to an internal OpenClaw message id instead of a real Slack thread_ts, and the Slack outbound path gives that replyToId priority over the known thread anchor.

This appears in inter-session / subagent-completion flows where the current message is an internal event, not the original Slack message.

Root Cause

Root cause hypothesis

Fix Action

Fix / Workaround

A local runtime hotfix that only accepts replyToId values matching Slack ts format appears to stop the recurrence in affected environments.

PR fix notes

PR #69429: fix(slack): preserve thread anchors over internal reply ids

Description (problem / solution / changelog)

Summary

  • validate Slack replyToId values before treating them as thread_ts
  • fall back to the known threadId anchor when replyToId is an internal OpenClaw message id
  • add regression coverage for the send path plus Slack threading transport helpers

Root cause

Slack-specific reply routing accepted any non-empty replyToId as a thread reference. In resumed turns triggered by internal events, [[reply_to_current]] could resolve to an internal OpenClaw message id instead of a real Slack thread_ts, which then overrode the valid Slack thread anchor and leaked the reply to channel root.

Validation

  • pnpm test extensions/slack/src/channel.test.ts
  • pnpm test extensions/slack/src/threading.test.ts
  • pnpm check

Closes #68790.

Changed files

  • extensions/slack/src/channel.test.ts (modified, +54/-0)
  • extensions/slack/src/channel.ts (modified, +6/-5)
  • extensions/slack/src/outbound-adapter.test.ts (modified, +42/-0)
  • extensions/slack/src/outbound-adapter.ts (modified, +5/-2)
  • extensions/slack/src/thread-ts.ts (added, +26/-0)
RAW_BUFFERClick to expand / collapse

Summary

Slack replies can leak to the channel root when [[reply_to_current]] resolves to an internal OpenClaw message id instead of a real Slack thread_ts, and the Slack outbound path gives that replyToId priority over the known thread anchor.

This appears in inter-session / subagent-completion flows where the current message is an internal event, not the original Slack message.

User-visible symptom

A reply that should stay inside an existing Slack thread is posted as a new top-level channel message.

Reproduction shape

This is intermittent, but the failure pattern is consistent:

  1. A Slack thread is active and the agent session is correctly thread-bound.
  2. A resumed turn is triggered by an internal event, for example:
    • subagent completion
    • inter-session completion/update event
    • another internal message delivered into the agent session
  3. The assistant emits [[reply_to_current]] in the final reply.
  4. The current message for that turn is now an internal OpenClaw message, so the resolved replyToId is an internal message id, not a Slack ts like 1776546991.037129.
  5. Slack outbound/reply transport uses replyToId before the known threadId / replyThreadTs.
  6. The resulting Slack send loses the real thread anchor and posts to channel root.

Why this is distinct from older Slack thread_ts bugs

Earlier Slack issues focused on:

  • missing thread_ts in delivery context
  • DM thread persistence
  • routed reply normalization gaps
  • inter-agent messages surfacing visibly

This issue is a separate guardrail failure:

a non-Slack internal reply id is allowed to override a valid Slack thread anchor.

Even if thread context is otherwise present, the wrong priority rule can still break delivery.

Root cause hypothesis

Slack-specific outbound logic accepts payload.replyToId too broadly.

In the failing path, replyToId is an internal OpenClaw message id, not a Slack ts. If that value is used as the effective reply reference before threadId / replyThreadTs, Slack thread routing breaks.

The fix should be Slack-specific validation, not a generic assumption that any reply id is usable as a Slack thread reference.

Proposed fix

In Slack outbound / reply transport logic:

  • only treat replyToId as a Slack reply reference if it matches Slack ts format, e.g. /^\\d+\\.\\d+$/
  • otherwise ignore it and fall back to the known Slack threadId / replyThreadTs

That validation likely needs to be applied consistently across:

  • outbound send path
  • outbound session route resolution
  • auto-thread resolution / reply transport helpers

Acceptance criteria

  1. If replyToId is an internal OpenClaw id, it must not override a valid Slack thread anchor.
  2. A resumed turn triggered by subagent completion should still reply into the original Slack thread.
  3. [[reply_to_current]] remains usable for real Slack reply ids.
  4. Existing valid Slack thread replies continue to work.

Additional note

A local runtime hotfix that only accepts replyToId values matching Slack ts format appears to stop the recurrence in affected environments.

extent analysis

TL;DR

Validate replyToId in Slack outbound logic to ensure it matches the Slack ts format before using it as a reply reference.

Guidance

  • Implement Slack-specific validation for replyToId to check if it matches the Slack ts format (e.g., /^\\d+\\.\\d+$/) before using it as a reply reference.
  • Apply this validation consistently across the outbound send path, outbound session route resolution, and auto-thread resolution/reply transport helpers.
  • If replyToId does not match the Slack ts format, ignore it and fall back to the known Slack threadId / replyThreadTs.
  • Verify that the fix works by testing resumed turns triggered by subagent completion and ensuring that replies are posted to the original Slack thread.

Example

if (/^\d+\.\d+$/.test(payload.replyToId)) {
  // Use replyToId as the reply reference
} else {
  // Fall back to threadId / replyThreadTs
}

Notes

The proposed fix assumes that the Slack ts format is the only valid format for replyToId. If other formats are valid, the validation logic may need to be adjusted.

Recommendation

Apply the proposed fix to validate replyToId in Slack outbound logic, as it addresses the root cause of the issue and ensures that replies are posted to the correct thread.

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: internal replyToId can override valid thread anchor and leak replies to channel root [1 pull requests, 1 comments, 2 participants]