can1357/oh-my-pi · warning · ToolError

inspect_image request aborted.

Error message

inspect_image request aborted.

What it means

The inspect_image tool sends the image and question to a configured vision model via a one-shot LLM request. When that request finishes with stopReason "aborted" (and the abort did not come from the tool's own inspect_image.timeoutMs timer), the tool converts it into this ToolError. It signals that the caller or the surrounding session cancelled the request before the vision model produced an answer.

Source

Thrown at packages/coding-agent/src/tools/inspect-image.ts:320

				{
					apiKey: modelRegistry.resolver(model, this.session.getSessionId?.() ?? undefined),
					signal: effectiveSignal,
					reasoning,
				},
				{ telemetry, oneshotKind: "inspect_image", completeImpl: this.completeImageRequest },
			);
		} catch (error) {
			if (error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError")) {
				if (timedOut()) throw new ToolError(formatTimeoutMessage());
			}
			throw error;
		}

		if (response.stopReason === "error") {
			throw new ToolError(response.errorMessage ?? "inspect_image request failed.");
		}
		if (response.stopReason === "aborted") {
			if (timedOut()) throw new ToolError(formatTimeoutMessage());
			throw new ToolError("inspect_image request aborted.");
		}

		const text = extractTextContent(response);
		if (!text) {
			throw new ToolError("inspect_image model returned no text output.");
		}

		return {
			content: [{ type: "text", text }],
			details: {
				model: `${model.provider}/${model.id}`,
				imagePath: imageInput.resolvedPath,
				mimeType: imageInput.mimeType,
				usage: response.usage,
			},
		};
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-run the inspect_image call without cancelling it (avoid sending a new user/abort signal mid-request).
  2. If aborts are frequent, check whether the enclosing agent loop or RPC client has an aggressive cancellation path that aborts tool calls early.
  3. If you actually hit the timeout path, raise the inspect_image.timeoutMs setting (0 disables) instead of treating this as an abort.

Example fix

// before: aborting the request when the user cancels mid-inspection
const controller = new AbortController();
userCancelEvent.then(() => controller.abort());
await inspectImage.execute(id, params, controller.signal); // -> "inspect_image request aborted."
// after: keep the signal alive until inspection completes, or retry after cancel
if (!cancelled) {
  const result = await inspectImage.execute(id, params, controller.signal);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (signal?.aborted) {
  throw new Error("Skip inspect_image: already cancelled.");
}

Type guard

function isAbortToolError(err: unknown): boolean {
  return err instanceof Error && err.message === "inspect_image request aborted.";
}

Try / catch

try {
  const result = await inspectImage.execute(id, params, signal);
} catch (err) {
  if (isAbortToolError(err)) {
    // expected on user cancel — log and continue
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling the inspect_image tool (or its execute() method) while the supplied AbortSignal is triggered by the user/session; the oneshot LLM call then resolves with stopReason "aborted" instead of throwing. Only fires when timedOut() is false — a timeout abort is reported as a timeout message instead.

Common situations: User presses Escape / cancels the agent turn while an image inspection is in flight; an SDK or RPC consumer cancels the tool call; a parent operation aborts its signal that was forwarded into execute().

Related errors


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