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

  1. No fix needed if intentional cancellation — this is the expected abort path; handle/suppress the abort in the caller.
  2. Increase task.maxConcurrency if tasks are routinely aborted while queued too long (if the abort stems from a timeout).
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f1a6ae6b2d2fd459. Report an issue: GitHub.