fix(background-agent): handle session.error and prevent zombie queue starts

Marks background tasks as error on session.error to release concurrency immediately, and skips/removes error tasks from queues to avoid zombie starts.
This commit is contained in:
YeonGyu-Kim
2026-02-12 18:26:03 +09:00
parent ff8a5f343a
commit 1ceaaa4311
7 changed files with 490 additions and 79 deletions
@@ -0,0 +1,46 @@
import { subagentSessions } from "../claude-code-session-state"
import type { BackgroundTask } from "./types"
export function cleanupTaskAfterSessionEnds(args: {
task: BackgroundTask
tasks: Map<string, BackgroundTask>
idleDeferralTimers: Map<string, ReturnType<typeof setTimeout>>
completionTimers: Map<string, ReturnType<typeof setTimeout>>
cleanupPendingByParent: (task: BackgroundTask) => void
clearNotificationsForTask: (taskId: string) => void
releaseConcurrencyKey?: (key: string) => void
}): void {
const {
task,
tasks,
idleDeferralTimers,
completionTimers,
cleanupPendingByParent,
clearNotificationsForTask,
releaseConcurrencyKey,
} = args
const completionTimer = completionTimers.get(task.id)
if (completionTimer) {
clearTimeout(completionTimer)
completionTimers.delete(task.id)
}
const idleTimer = idleDeferralTimers.get(task.id)
if (idleTimer) {
clearTimeout(idleTimer)
idleDeferralTimers.delete(task.id)
}
if (task.concurrencyKey && releaseConcurrencyKey) {
releaseConcurrencyKey(task.concurrencyKey)
task.concurrencyKey = undefined
}
cleanupPendingByParent(task)
clearNotificationsForTask(task.id)
tasks.delete(task.id)
if (task.sessionID) {
subagentSessions.delete(task.sessionID)
}
}