Summary
openclaw system event --text "..." --mode now silently fails to deliver events. The CLI returns ok, the heartbeat fires, but the system event is never queued because wake() in src/cron/service/timer.ts calls enqueueSystemEvent(text) without passing a sessionKey.
This is a regression from the fix for #510, which correctly added session key resolution to cron job execution paths (line 454) but missed the wake() function (line 632) in the same file.
Steps to reproduce
- Set up any integration that calls
openclaw system event --text "..." --mode now (e.g. an IRC mention watcher)
- Trigger the event while no user message is active
- CLI returns
ok
- Agent is never woken — event is silently dropped
The event appears to work if a user message arrives at the same time, because the system event gets bundled into that turn's context. But standalone --mode now wakes never trigger an agent turn.
Root cause
wake() at src/cron/service/timer.ts:632:
state.deps.enqueueSystemEvent(text); // ← no sessionKey or agentId
The enqueueSystemEvent wrapper in server-cron.ts:158 resolves the session key from agentId, but wake() passes neither. The underlying requireSessionKey() in system-events.ts throws on empty keys, and the error is swallowed upstream.
Compare with cron job execution at line 454 which correctly passes both:
state.deps.enqueueSystemEvent(text, {
agentId: job.agentId,
sessionKey: job.sessionKey,
contextKey: \`cron:\${job.id}\`,
});
And the HTTP hooks path in server/hooks.ts which also works correctly:
enqueueSystemEvent(value.text, { sessionKey });
Fix
Three-line change — pass agentId to the wrapper so it can resolve the session key:
export function wake(
state: CronServiceState,
opts: { mode: "now" | "next-heartbeat"; text: string },
) {
const text = opts.text.trim();
if (!text) {
return { ok: false } as const;
}
- state.deps.enqueueSystemEvent(text);
+ const agentId = state.deps.defaultAgentId ?? DEFAULT_AGENT_ID;
+ state.deps.enqueueSystemEvent(text, { agentId });
if (opts.mode === "now") {
- state.deps.requestHeartbeatNow({ reason: "wake" });
+ state.deps.requestHeartbeatNow({ reason: "wake", agentId });
}
return { ok: true } as const;
}
Environment
- OpenClaw version: 2026.2.16 (b251533)
- OS: Linux 6.18.9-200.fc43.x86_64 (Fedora 43)
- Node: v22.22.0
- Install method: pnpm build from source
Related
Summary
openclaw system event --text "..." --mode nowsilently fails to deliver events. The CLI returnsok, the heartbeat fires, but the system event is never queued becausewake()insrc/cron/service/timer.tscallsenqueueSystemEvent(text)without passing asessionKey.This is a regression from the fix for #510, which correctly added session key resolution to cron job execution paths (line 454) but missed the
wake()function (line 632) in the same file.Steps to reproduce
openclaw system event --text "..." --mode now(e.g. an IRC mention watcher)okThe event appears to work if a user message arrives at the same time, because the system event gets bundled into that turn's context. But standalone
--mode nowwakes never trigger an agent turn.Root cause
wake()atsrc/cron/service/timer.ts:632:The
enqueueSystemEventwrapper inserver-cron.ts:158resolves the session key fromagentId, butwake()passes neither. The underlyingrequireSessionKey()insystem-events.tsthrows on empty keys, and the error is swallowed upstream.Compare with cron job execution at line 454 which correctly passes both:
And the HTTP hooks path in
server/hooks.tswhich also works correctly:Fix
Three-line change — pass
agentIdto the wrapper so it can resolve the session key:export function wake( state: CronServiceState, opts: { mode: "now" | "next-heartbeat"; text: string }, ) { const text = opts.text.trim(); if (!text) { return { ok: false } as const; } - state.deps.enqueueSystemEvent(text); + const agentId = state.deps.defaultAgentId ?? DEFAULT_AGENT_ID; + state.deps.enqueueSystemEvent(text, { agentId }); if (opts.mode === "now") { - state.deps.requestHeartbeatNow({ reason: "wake" }); + state.deps.requestHeartbeatNow({ reason: "wake", agentId }); } return { ok: true } as const; }Environment
Related