Bug
In multi-agent OpenClaw deployments, all agents share the same memory namespace because resolveHookAgentId and several other call sites fall back to "main" when ctx.agentId is empty, without first trying to parse the agent id from the session key.
Affected code (index.ts)
| Location |
Code |
Line 212 (resolveHookAgentId) |
return explicitAgentId || parseAgentIdFromSessionKey(sessionKey) || "main" |
Line ~2526 (before_agent_start) |
const agentId = typeof ctx.agentId === "string" && ctx.agentId.trim() ? ctx.agentId.trim() : "main" |
Line ~2547 (before_prompt_build) |
Same pattern |
The root cause: when ctx.agentId is truthy but incorrect (e.g. OpenClaw passes "main" as a default), or when ctx.agentId is empty, the code never reaches parseAgentIdFromSessionKey which would correctly extract the agent name from session keys like agent:kent:hive-chat:group:....
Impact
- All agents load memories from the
main agent namespace
- Cross-contamination of memory between agents
- Debug log shows:
injecting 1 memories into context for agent main even when the session key clearly contains a different agent id
Suggested fix
Prioritize parseAgentIdFromSessionKey(sessionKey) over ctx.agentId in all resolution paths:
// resolveHookAgentId
return parseAgentIdFromSessionKey(sessionKey) || explicitAgentId || "main";
// before_agent_start / before_prompt_build
const agentId = parseAgentIdFromSessionKey(sessionKey)
|| (typeof ctx.agentId === "string" && ctx.agentId.trim() ? ctx.agentId.trim() : "main");
We have applied this fix locally and confirmed it resolves the issue.
Environment
- OpenClaw with 8 agents
- memory-lancedb-pro latest (cloned from main)
- Session key format:
agent:<agentId>:<channel>:<scope>
Bug
In multi-agent OpenClaw deployments, all agents share the same memory namespace because
resolveHookAgentIdand several other call sites fall back to"main"whenctx.agentIdis empty, without first trying to parse the agent id from the session key.Affected code (
index.ts)resolveHookAgentId)return explicitAgentId || parseAgentIdFromSessionKey(sessionKey) || "main"before_agent_start)const agentId = typeof ctx.agentId === "string" && ctx.agentId.trim() ? ctx.agentId.trim() : "main"before_prompt_build)The root cause: when
ctx.agentIdis truthy but incorrect (e.g. OpenClaw passes"main"as a default), or whenctx.agentIdis empty, the code never reachesparseAgentIdFromSessionKeywhich would correctly extract the agent name from session keys likeagent:kent:hive-chat:group:....Impact
mainagent namespaceinjecting 1 memories into context for agent maineven when the session key clearly contains a different agent idSuggested fix
Prioritize
parseAgentIdFromSessionKey(sessionKey)overctx.agentIdin all resolution paths:We have applied this fix locally and confirmed it resolves the issue.
Environment
agent:<agentId>:<channel>:<scope>