-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
cron: encode sessionKey when deriving jobId to support channel-native conversation IDs #64030
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Problem
runtime.channel.routing.buildAgentSessionKey(...)passes the channel-provided id segment through verbatim. For DingTalk, that segment is the platform's nativeconversationId, which routinely contains/. A real example:This sessionKey is valid everywhere else in the runtime (routing, dedup, session locks, the agent session store, logs), but cron rejects it at job creation:
src/cron/session-target.ts:8-10The same guard is mirrored in
src/cron/run-log.ts:58-67(assertSafeCronRunLogJobId).Impact
Cron jobs cannot target any DingTalk group conversation. This is the entire group-chat surface of the DingTalk channel — not a corner case. Other channels whose native IDs are base64-ish are likely to hit the same wall.
Root cause
The guard exists for a real reason:
src/cron/run-log.ts:69-78builds run-log filesystem paths directly fromjobId:And
jobIdis derived fromsessionKey. So a/in sessionKey would become a real path-traversal vector. The blocklist is correct defense; the design choice that forced it — using a sessionKey-derived string directly as a filename — is where the mismatch lives.Notably, openclaw's own agent session store does not have this problem.
src/config/sessions/types.ts:315generates a random UUID:and
src/config/sessions/paths.ts:248-251uses that UUID as the filename, keeping sessionKey as an opaque map key insidesessions.json. Cron is the only subsystem that couples the filesystem name to sessionKey's character set.Proposed fix (minimal)
Encode sessionKey when deriving jobId, e.g.:
assertSafeCronSessionTargetIdcan drop the/\check on sessionKey (it no longer touches the filesystem directly).assertSafeCronRunLogJobIdstays as a belt-and-suspenders guard against anything outside the base64url alphabet.Alternative considered
Normalizing inside
buildAgentSessionKeyitself — rejected. It would change every existing persisted sessionKey across all channels and all subsystems (dedup, session locks, the agent session store'ssessions.jsonkeys), requiring a versioned prefix and migration for a problem that only cron actually has.Repro
session:<that sessionKey>as the target.INVALID_CRON_SESSION_TARGET_ID_ERRORis thrown at job creation.