CopilotKit / CopilotKit/outpost

Slack adapter correctness — blocks the Slack go-live acceptance criteria

Open
#137 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: integrations roadmap roadmap: now
Dominant language
TypeScript
Stars
7
Forks
3
Avg merge
7d 16h
Merged PRs (30d)
15

Description

Why this blocks the Slack go-live

The Slack adapter has correctness bugs that #63's acceptance checklist cannot pass. Worth
fixing before starting #62, because the roadmap currently frames Slack as a wiring task —
the code is complete, but it is not correct.

Found during a code review of an unrelated PR; each item was verified against source.

Findings

1. postResponse discards the message ts — feedback tracking cannot work.
packages/outpost/shared/src/platforms/slack.ts hardcodes return undefined instead of
returning chat.postMessage's ts. The caller at
packages/outpost/queue/src/handlers/ai-response.ts:218 assigns that return to
externalCommentId, so Outpost never records which Slack message it posted. #63 explicitly
tests the AI response posting back and feedback being attributed — that cannot pass.

2. Missing event.ts yields threadId: '', so unrelated tickets collide.
parseInboundEvent produces threadId: '' when ts is absent, and sourceId becomes
"C123:". Every malformed event maps onto the same ticket lookup key.

3. Unvalidated cast; bot_id/subtype never checked — bot-loop risk.
parseInboundEvent casts rawEvent without inspecting the declared bot_id/subtype
fields, so the bot can respond to bot messages.

4. Slack's 3000-char Block Kit section cap is ignored.
The whole response goes into one section. Over the cap, chat.postMessage throws
invalid_blocks, and the caller only logs — so a long AI answer is silently dropped and the
user gets nothing. response.parts and response.buttons are also ignored, which is the
other half of why there is no feedback path.

5. mrkdwn is fed GitHub Markdown. Blocks declare type: 'mrkdwn' but receive
**bold** and [text](url), which Slack renders literally.

6. Empty-string profile fields defeat the fallbacks. fetchUserInfo uses ?? on
display_name/email/image_72; Slack returns "" for unset profile fields, and "" is not
nullish, so displayName becomes '' rather than falling back to real_name.

7. Blanket catch reports success. The catch around users.info turns a revoked token,
a missing scope, or a rate limit into a "success" that persists the raw Slack ID as the
username, with only a console.warn.

Acceptance criteria

  • postResponse returns the posted message ts; a Slack ticket ends up with a non-null
    externalCommentId, and 👍/👎 attribution works end to end
  • A missing ts is rejected rather than producing an empty threadId
  • Bot-authored messages (bot_id / subtype) are ignored, with a test
  • Responses over 3000 chars are split across blocks and post successfully
  • Markdown is converted to Slack mrkdwn (or blocks are built from response.parts)
  • Empty-string profile fields fall through to the next fallback
  • fetchUserInfo distinguishes auth/scope/rate-limit failures from a genuinely missing user

Related: #62, #63

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/outpost/shared/src/platforms/slack.ts, then trace the caller at packages/outpost/queue/src/handlers/ai-response.ts:218 and the #63 acceptance checklist. Verify each listed Slack adapter failure, including message IDs, event validation, block limits, formatting, profile fallbacks, and user-info errors. Done means all acceptance criteria pass, including tests for bot-authored messages and end-to-end feedback attribution.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.