#10686: fix(slack): use thread-level sessions for channels to prevent context mixing
channel: slack
size: S
Cluster:
Slack Thread Management Improvements
## Problem
All messages in a Slack channel share a single session, causing context from different threads to mix together. When users have multiple conversations in different threads of the same channel, the agent sees combined context from all threads, leading to confused responses.
**Current session key:** `slack:channel:${channelId}` (no thread identifier)
This means Thread A and Thread B in the same channel both use:
```
agent:main:slack:channel:C0AA0BB6S3B
```
The LLM sees mixed context from ALL threads, causing it to:
- Reference wrong topics
- Confuse user identities across threads
- Give incoherent responses
## Solution
### 1. Thread-level session keys (main fix)
Each message in channels/groups now gets its own session based on `thread_ts`:
- **Thread replies:** use the parent thread's ts
- **New messages:** use the message's own ts (becomes thread root)
- **DMs:** unchanged (no thread-level sessions needed)
**New session key format:** `slack:channel:${channelId}:thread:${threadTs}`
### 2. Increased thread cache TTL
Changed from **60 seconds** to **6 hours**. Users often pause conversations for minutes or hours, and the short TTL caused unnecessary API calls and thread resolution failures.
### 3. Increased cache size
Changed from **500** to **10,000** entries to support busy workspaces with many active threads.
## Files Changed
| File | Change |
|------|--------|
| `src/slack/monitor/message-handler/prepare.ts` | Use `canonicalThreadId` for all channel messages |
| `src/slack/monitor/thread-resolution.ts` | Increase cache TTL and size |
## Testing
1. Create two threads in the same Slack channel
2. In Thread A: tell the bot your name is "Alice" and ask about "billing"
3. In Thread B: tell the bot your name is "Bob" and ask about "API"
4. Reply in Thread A and ask "what's my name?" - should say "Alice"
5. Check sessions with `openclaw sessions list --kinds slack` - each thread should have a unique session key with `:thread:` suffix
## Before/After
**Before:**
```
agent:main:slack:channel:C0AA0BB6S3B ← both threads share this
```
**After:**
```
agent:main:slack:channel:C0AA0BB6S3B:thread:1770408518.451689 ← Thread A
agent:main:slack:channel:C0AA0BB6S3B:thread:1770408522.168859 ← Thread B
```
## Related Issues
- Fixes context bleed issues related to #758
- Related to #4927 (thread.inheritParent)
---
Tested locally with OpenClaw v2026.2.x. Happy to add unit tests if needed!
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Updates Slack session routing so channel/group messages use a per-thread session key (`:thread:<ts>`) to prevent cross-thread context mixing.
- New top-level channel/group messages start a new thread session based on the message `ts`; replies reuse the parent thread `ts`.
- Increases the Slack `thread_ts` resolver cache TTL (60s → 6h) and max size (500 → 10k) to reduce history lookups and improve stability in active workspaces.
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge after fixing one thread-session regression.
- Core change to thread-level session keys is straightforward and consistent with `resolveThreadSessionKeys`, and the cache adjustments are localized. However, `previousTimestamp` is still read from the base session key, which will misreport timestamps for the new per-thread sessions in channels/groups.
- src/slack/monitor/message-handler/prepare.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22433: Slack: fix thread context loss after session reset
by stgarrity · 2026-02-21
86.0%
#19083: Slack: preserve per-thread context and consistent thread replies
by jkimbo · 2026-02-17
84.6%
#19403: feat(slack): add dm.threadSession option for per-message thread ses...
by Vasiliy-Bondarenko · 2026-02-17
83.2%
#9181: feat(slack): add per-channel thread config override
by halbotley · 2026-02-05
83.1%
#22982: fix: prevent stale threadId from routing subagent announces to wron...
by unboxed-ai · 2026-02-21
82.7%
#5935: fix(slack): persist thread starter body across thread messages
by thisischappy · 2026-02-01
82.1%
#20389: fix(slack): inject thread history on first thread turn, not only on...
by lafawnduh1966 · 2026-02-18
82.1%
#22485: fix(slack): use threadId from delivery context as threadTs fallback...
by dorukardahan · 2026-02-21
82.0%
#16186: fix(slack): thread history on subsequent turns, inbound meta contex...
by markshields-tl · 2026-02-14
81.6%
#15969: fix: per-thread session isolation for Slack DMs when replyToMode is...
by neeravmakwana · 2026-02-14
81.0%