fix: avoid duplicate orphaned subagent resumes

This commit is contained in:
Tak Hoffman
2026-03-24 12:03:28 -05:00
parent 44d5e6d672
commit 2990446b21
2 changed files with 35 additions and 2 deletions

View File

@@ -383,4 +383,37 @@ describe("subagent-orphan-recovery", () => {
expect(result.skipped).toBe(1);
expect(gateway.callGateway).toHaveBeenCalledOnce();
});
it("does not retry a session after the gateway accepted resume but run remap failed", async () => {
vi.mocked(gateway.callGateway).mockResolvedValue({ runId: "new-run" } as never);
vi.mocked(subagentRegistry.replaceSubagentRunAfterSteer).mockReturnValue(false);
vi.mocked(sessions.loadSessionStore).mockReturnValue({
"agent:main:subagent:test-session-1": {
sessionId: "session-abc",
updatedAt: Date.now(),
abortedLastRun: true,
},
});
const activeRuns = new Map<string, SubagentRunRecord>();
activeRuns.set("run-1", createTestRunRecord());
const resumedSessionKeys = new Set<string>();
const first = await recoverOrphanedSubagentSessions({
getActiveRuns: () => activeRuns,
resumedSessionKeys,
});
const second = await recoverOrphanedSubagentSessions({
getActiveRuns: () => activeRuns,
resumedSessionKeys,
});
expect(first.recovered).toBe(1);
expect(first.failed).toBe(0);
expect(second.recovered).toBe(0);
expect(second.skipped).toBe(1);
expect(gateway.callGateway).toHaveBeenCalledOnce();
expect(sessions.updateSessionStore).toHaveBeenCalledOnce();
});
});

View File

@@ -108,9 +108,9 @@ async function resumeOrphanedSession(params: {
});
if (!remapped) {
log.warn(
`resumed orphaned session ${params.sessionKey} but remap failed (old run already removed); treating as failure`,
`resumed orphaned session ${params.sessionKey} but remap failed (old run already removed); treating resume as accepted to avoid duplicate restarts`,
);
return false;
return true;
}
log.info(`resumed orphaned session: ${params.sessionKey}`);
return true;