Skip to content

Commit fe9a7c4

Browse files
author
Sid
authored
fix(cron): force main-target system events onto main session (#28898)
Ignore persisted sessionKey overrides for sessionTarget=main jobs so cron system events consistently route to the agent main session after upgrades. Closes #28770
1 parent 2851926 commit fe9a7c4

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

src/cron/service.runs-one-shot-main-job-disables-it.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ describe("CronService", () => {
509509
await store.cleanup();
510510
});
511511

512-
it("passes agentId + sessionKey to runHeartbeatOnce for main-session wakeMode now jobs", async () => {
512+
it("passes agentId and resolves main session for wakeMode now main jobs", async () => {
513513
const runHeartbeatOnce = vi.fn(async () => ({ status: "ran" as const, durationMs: 1 }));
514514

515515
const { store, cron, enqueueSystemEvent, requestHeartbeatNow } =
@@ -534,13 +534,13 @@ describe("CronService", () => {
534534
expect.objectContaining({
535535
reason: `cron:${job.id}`,
536536
agentId: "ops",
537-
sessionKey,
537+
sessionKey: undefined,
538538
}),
539539
);
540540
expect(requestHeartbeatNow).not.toHaveBeenCalled();
541541
expect(enqueueSystemEvent).toHaveBeenCalledWith(
542542
"hello",
543-
expect.objectContaining({ agentId: "ops", sessionKey }),
543+
expect.objectContaining({ agentId: "ops", sessionKey: undefined }),
544544
);
545545

546546
cron.stop();
@@ -578,7 +578,7 @@ describe("CronService", () => {
578578
expect(requestHeartbeatNow).toHaveBeenCalledWith(
579579
expect.objectContaining({
580580
reason: `cron:${job.id}`,
581-
sessionKey,
581+
sessionKey: undefined,
582582
}),
583583
);
584584
expect(job.state.lastStatus).toBe("ok");

src/cron/service/timer.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,9 +640,12 @@ export async function executeJobCore(
640640
: 'main job requires payload.kind="systemEvent"',
641641
};
642642
}
643+
// main-target cron jobs should always resolve via the agent's main session.
644+
// Avoid forwarding persisted channel session keys from legacy records.
645+
const targetMainSessionKey = undefined;
643646
state.deps.enqueueSystemEvent(text, {
644647
agentId: job.agentId,
645-
sessionKey: job.sessionKey,
648+
sessionKey: targetMainSessionKey,
646649
contextKey: `cron:${job.id}`,
647650
});
648651
if (job.wakeMode === "now" && state.deps.runHeartbeatOnce) {
@@ -659,7 +662,7 @@ export async function executeJobCore(
659662
heartbeatResult = await state.deps.runHeartbeatOnce({
660663
reason,
661664
agentId: job.agentId,
662-
sessionKey: job.sessionKey,
665+
sessionKey: targetMainSessionKey,
663666
});
664667
if (
665668
heartbeatResult.status !== "skipped" ||
@@ -677,7 +680,7 @@ export async function executeJobCore(
677680
state.deps.requestHeartbeatNow({
678681
reason,
679682
agentId: job.agentId,
680-
sessionKey: job.sessionKey,
683+
sessionKey: targetMainSessionKey,
681684
});
682685
return { status: "ok", summary: text };
683686
}
@@ -698,7 +701,7 @@ export async function executeJobCore(
698701
state.deps.requestHeartbeatNow({
699702
reason: `cron:${job.id}`,
700703
agentId: job.agentId,
701-
sessionKey: job.sessionKey,
704+
sessionKey: targetMainSessionKey,
702705
});
703706
return { status: "ok", summary: text };
704707
}

0 commit comments

Comments
 (0)