can1357/oh-my-pi · info · Error
Aborted before execution
Error message
Aborted before execution
What it means
The Task tool's registered background job waits on the spawn semaphore, then re-checks the abort signal before executing. If the semaphore was never acquired (acquire threw due to abort) or the run signal aborted during/after acquisition, the job marks progress aborted, fires onSettled(true), and throws 'Aborted before execution' — the task never starts.
Source
Thrown at packages/coding-agent/src/task/index.ts:1129
if (!semaphoreHeld) return;
semaphoreHeld = false;
this.#releaseSpawnSemaphore();
};
try {
await semaphore.acquire(runSignal);
semaphoreHeld = true;
} catch {
// Fall through so an acquire-time abort goes through the same
// path as the post-acquire race below: progress + onSettled
// have to fire even when the spawn never reached the executor,
// otherwise the batch aggregate state stays "running" forever.
}
const acquiredAt = Date.now();
if (!semaphoreHeld || runSignal.aborted) {
releasePermit();
progress.status = "aborted";
onSettled?.(true);
throw new Error("Aborted before execution");
}
try {
markRunning();
progress.status = "running";
await reportProgress(
`Running background task ${agentId}...`,
buildDetails() as unknown as Record<string, unknown>,
);
const forwardSyncProgress: AgentToolUpdateCallback<TaskToolDetails> = async update => {
const nextProgress = update.details?.progress?.[0];
if (nextProgress) {
// The job body owns status and identity (id/index/agent);
// copy only the live metrics the subagent streams so the
// polling row reflects the resolved model, reasoning level,
// and running counters without reverting the "running"
// status back to the subagent's initial "pending" snapshot.
progress.modelRole = nextProgress.modelRole ?? progress.modelRole;
progress.resolvedModel = nextProgress.resolvedModel;View on GitHub (pinned to 9690622007)
Solutions
- No fix needed if intentional cancellation — this is the expected abort path; handle/suppress the abort in the caller.
- Increase task.maxConcurrency if tasks are routinely aborted while queued too long (if the abort stems from a timeout).
- Re-issue the task after the session is un-aborted; the agent remains resumable per the follow-up hint.
Defensive patterns
Strategy: try-catch
Validate before calling
// check before spawning a background task
if (signal?.aborted) {
console.log("skip: session already aborted");
} else if (pendingTasks >= maxConcurrency) {
console.log("task will queue; abort during queueing throws 'Aborted before execution'");
} Try / catch
try {
await taskTool.run(spawnParams);
} catch (err) {
if (err instanceof Error && err.message === "Aborted before execution") {
// intentional cancellation: update batch state, do not surface as failure
return { aborted: true };
}
throw err;
} Prevention
- Don't abort the parent signal while background tasks are still queued, or treat this outcome as expected.
- Size task.maxConcurrency so queued waits stay short.
- Check progress.status === "aborted" to distinguish cancellation from real failures.
When it happens
Trigger: TaskTool background spawn where the session/signal is aborted while the job is queued waiting for a concurrency permit, or aborted in the window between semaphore.acquire() resolving and execution beginning.
Common situations: User presses Esc/cancels while several background tasks are queued behind task.maxConcurrency, an ESC-interrupted agent turn aborting its child Task calls, or a timeout aborting the parent signal.
Related errors
- Request was aborted
- Auth broker request aborted
- OAuth refresh ownership aborted by caller
- Request was aborted.
- AbortError
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f1a6ae6b2d2fd459.
Report an issue: GitHub.