Skip to content

DMs broken: empty threadTs causes invalid_thread_ts and invalid_arguments #268

@dcamposbiorender

Description

@dcamposbiorender

Bug

Direct messages to a bot fail with invalid_thread_ts (from chat.postMessage) and invalid_arguments (from chatStream) because handleMessageEvent sets threadTs = "" for top-level DM messages.

Root Cause

In @chat-adapter/slack, handleMessageEvent computes threadTs differently for DMs vs channels:

const threadTs = isDM ? event.thread_ts || "" : event.thread_ts || event.ts;

For channels, top-level messages fall back to event.ts (a valid Slack timestamp).
For DMs, top-level messages fall back to "" (empty string).

This empty string propagates through encodeThreadIddecodeThreadId → Slack API calls:

Method What happens Slack error
postMessage thread_ts: "" invalid_thread_ts
chatStream thread_ts: "" invalid_arguments
startTyping Silently skipped (if (!threadTs) return) No error but no typing indicator
postEphemeral Works — already uses threadTs || void 0

Reproduction

  1. Create a bot using chat + @chat-adapter/slack
  2. Register an onNewMention handler that calls thread.post("hello")
  3. Send a DM to the bot (not in a channel)
  4. Observe: An API error occurred: invalid_thread_ts
  5. If using streaming (thread.post(result.fullStream)): An API error occurred: invalid_arguments

Channel mentions work fine because they fall back to event.ts.

Fix

Use the same fallback for both DMs and channels:

// Before (broken for DMs):
const threadTs = isDM ? event.thread_ts || "" : event.thread_ts || event.ts;

// After (works for both):
const threadTs = event.thread_ts || event.ts;

Additionally, postMessage and chatStream should defensively guard against empty threadTs (like postEphemeral already does):

// postMessage — 3 code paths
thread_ts: threadTs || void 0,

// chatStream
thread_ts: threadTs || void 0,

Workaround

We're using pnpm patch @chat-adapter/slack to apply both fixes. Happy to open a PR if preferred.

Versions

  • chat: 4.20.2
  • @chat-adapter/slack: 4.20.2
  • Bug also present in 4.18.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions