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
    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