#discord attaching to wrong session
1 messages · Page 1 of 1 (latest)
Thanks for the detailed write-up, George! 🦐 This is a classic session key mismatch issue.
Before diving in — what version are you running?
clawdbot --version
Version mismatches are the #1 cause of weird session bugs, so I need to rule that out first.
Based on your analysis, the issue is clear:
- ✅
ctx.SessionKeycorrectly hasagent:main:discord:channel:1460578963046006918 - ❌ But somewhere in the reply pipeline, it's falling back to
agent:main:main
Quick questions while we dig in:
- Does this happen in all Discord channels or just #instant-impact?
- Any routing bindings defined in your config? You mentioned defaults, but worth double-checking
- When did this start? After an update, config change, or has it always been this way?
The key places I'd check (after confirming version):
- Session resolution —
resolveSessionKey()should respectctx.SessionKeywhen set - Tool creation — Discord tools might be initialized with the wrong session scope
- LLM runner —
resolveSessionLane()might be transforming the key incorrectly
For reference:
- FAQ: https://docs.clawd.bot/start/faq
- Session docs: https://docs.clawd.bot/concepts/sessions
Let me know the version and those details, and we can narrow down where the session key is getting overridden!
clawdbot@2026.1.12-2
Thanks for the version! 2026.1.12-2 is very fresh (Jan 12). There might have been a recent regression.
Based on your analysis, the most likely culprits are:
1. Tool initialization with wrong session scope
Discord tools (message, react, etc.) might be created with agent:main:main instead of reading from ctx.SessionKey. Check where tools are instantiated in the Discord handler.
2. resolveSessionLane() in the LLM runner
This function might be transforming the channel-specific key back to the main session. Look for any logic that strips the :discord:channel:XXXX suffix.
3. Session init in reply path
initSessionState() in reply/session.ts might not be respecting ctx.SessionKey in all code paths.
Debugging steps:
- Add console logging right before the LLM call to confirm what session key is being passed:
console.log('LLM session key:', ctx.SessionKey)
-
Check the session resolution order in
resolveSessionKey()- make sure the explicitctx.SessionKeycheck happens before any fallback logic. -
Compare how WhatsApp handles this correctly vs Discord - you mentioned WhatsApp works. What differs in the session resolution?
Recent changes to check:
- Any changes to
resolveSessionLane()in the past few days? - Tool creation code for Discord provider?
- Session initialization in reply pipeline?
The fact that inbound works but outbound breaks suggests the session key is correct at the start but gets overwritten somewhere in the reply generation path. 🦐
Great analysis, George! This is really thorough. 🦐
Key insight from your debug logs:
The session file does contain the user message at 18:06:43, but Daphne responds as if she has no prior context. This means:
- ✅ Session file is being written correctly
- ❌ LLM is reading from the wrong session (
agent:main:main)
Most likely culprit:
Looking at resolveSessionKey():
const explicit = ctx.SessionKey?.trim();
if (explicit) return explicit;
The issue might be that somewhere in the reply pipeline, a different ctx object is being passed that doesn't have SessionKey set, OR there's another code path entirely that bypasses this logic.
Where to look:
-
Check
dispatchReplyFromConfig()→getReplyFromConfig()flow- Does the
ctxpassed here still haveSessionKey? - There might be a
ctx.clone()orctx.withDefaults()that strips it
- Does the
-
Check LLM runner (pi-embedded-runner.ts)
- Does it call
resolveSessionLane()which might override the session key? - The session lane resolution might not respect
ctx.SessionKey
- Does it call
-
Check tool creation in the reply path
- Discord tools might be initialized with a hardcoded
agent:main:mainscope
- Discord tools might be initialized with a hardcoded
Quick test:
Add logging immediately before the LLM call to confirm what ctx looks like at that exact point:
console.log('LLM call - ctx.SessionKey:', ctx.SessionKey)
console.log('LLM call - sessionKey being used:', sessionKey)
If ctx.SessionKey is present but the LLM still has no memory, then the issue is downstream - something is reading from the wrong session file after resolveSessionKey() runs.
If ctx.SessionKey is undefined, then the issue is upstream - the context is being replaced somewhere.
Which version of these two scenarios does your debug logging show? That will tell us exactly where to focus.
The latest gateway log shows exactly what you asked us to
capture:
[SESSION DEBUG] Resolved sessionKey:
agent:main:discord:channel:1460578963046006918
[SESSION DEBUG] Session entry exists: true, sessionId:
000d438a-4205-4377-a4e7-e341bc5769d3
So the context arriving in initSessionState still carries
the channel-specific key and the session store read the
right file. That confirms ctx.SessionKey is populated at
the moment we compute the session, so the upstream path
is intact—scenario 1 from your list.
What remains is to trace the downstream tooling/runner
path (runEmbeddedPiAgent, resolveSessionLane, tool
creation, etc.) to discover why the LLM is still reading
agent:main:main. We didn’t see any [LLM DEBUG] lines yet
(they’ll appear once the logged run actually reaches the
runner), so once another Discord reply goes through we’ll
know whether sessionCtx.SessionKey and sessionKey remain
correct all the way to the embedded runner.
Excellent! That narrows it down significantly. 🦐
Now we know the issue is downstream from initSessionState(). The session is resolved correctly, but something is overriding it before the LLM actually reads.
Next logging targets:
-
Inside
runEmbeddedPiAgent()- Right at the start, check ifsessionCtx.SessionKeyis still correct -
resolveSessionLane()- This is the #1 suspect. Check what it returns:console.log('resolveSessionLane input:', sessionCtx.SessionKey); console.log('resolveSessionLane output:', resolvedLane);It might be stripping
:discord:channel:XXXXand falling back to main -
Tool creation - When tools (discord, message, etc.) are instantiated, what session scope do they get?