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.
Solutions
- Re-run the inspect_image call without cancelling it (avoid sending a new user/abort signal mid-request).
- If aborts are frequent, check whether the enclosing agent loop or RPC client has an aggressive cancellation path that aborts tool calls early.
- 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
- Don't abort the signal forwarded to inspect_image unless you truly want to cancel.
- Distinguish timeout (inspect_image.timeoutMs) from external abort — only external aborts surface this message.
- Retry the inspection after an intentional cancel resolves.
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.
Appendix: 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)