{"record":{"id":"402d5faa3f697776","repo":"can1357/oh-my-pi","slug":"formattimeoutmessage","errorCode":null,"errorMessage":"${formatTimeoutMessage()}","messagePattern":"\\$\\{formatTimeoutMessage\\(\\)\\}","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/inspect-image.ts","lineNumber":311,"sourceCode":"\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{ type: \"image\", data: imageInput.data, mimeType: imageInput.mimeType },\n\t\t\t\t\t\t\t\t{ type: \"text\", text: params.question },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tapiKey: modelRegistry.resolver(model, this.session.getSessionId?.() ?? undefined),\n\t\t\t\t\tsignal: effectiveSignal,\n\t\t\t\t\treasoning,\n\t\t\t\t},\n\t\t\t\t{ telemetry, oneshotKind: \"inspect_image\", completeImpl: this.completeImageRequest },\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && (error.name === \"AbortError\" || error.name === \"TimeoutError\")) {\n\t\t\t\tif (timedOut()) throw new ToolError(formatTimeoutMessage());\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (response.stopReason === \"error\") {\n\t\t\tthrow new ToolError(response.errorMessage ?? \"inspect_image request failed.\");\n\t\t}\n\t\tif (response.stopReason === \"aborted\") {\n\t\t\tif (timedOut()) throw new ToolError(formatTimeoutMessage());\n\t\t\tthrow new ToolError(\"inspect_image request aborted.\");\n\t\t}\n\n\t\tconst text = extractTextContent(response);\n\t\tif (!text) {\n\t\t\tthrow new ToolError(\"inspect_image model returned no text output.\");\n\t\t}\n\n\t\treturn {","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/inspect-image.ts#L293-L329","documentation":"The one-shot vision LLM request aborted with AbortError/TimeoutError and the tool's own timeout signal (inspect_image.timeoutMs) was the cause, so it converts the abort into a descriptive ToolError stating the elapsed time and how to raise or disable the timeout. If the caller's signal aborted instead, the original error is rethrown.","triggerScenarios":"Vision request exceeded inspect_image.timeoutMs (settings) — slow provider, very large image, reasoning-heavy vision model, or a very low timeoutMs value; also network stalls pushing latency past the limit.","commonSituations":"timeoutMs set to a small value like 5000 while the vision model takes 20-60s; slow rate-limited provider; huge downscaled image increasing upload+inference time; thinking-enabled vision models adding latency.","solutions":["Increase inspect_image.timeoutMs in settings (e.g. 60000 or more).","Set inspect_image.timeoutMs to 0 to disable the timeout entirely.","Check provider status/latency or switch to a faster vision model via modelRoles.vision.","Reduce image size to cut upload and inference time."],"exampleFix":"// before\n{ \"inspect_image\": { \"timeoutMs\": 5000 } }\n// after\n{ \"inspect_image\": { \"timeoutMs\": 120000 } }","handlingStrategy":"retry","validationCode":"const timeoutMs = session.settings.get(\"inspect_image.timeoutMs\");\nif (typeof timeoutMs === \"number\" && timeoutMs > 0 && timeoutMs < 30000) {\n  // vision calls commonly need 30s+: raise timeoutMs or set 0 to disable\n}","typeGuard":null,"tryCatchPattern":"try {\n  await inspectImageTool.execute(id, params, signal);\n} catch (e) {\n  if (e instanceof ToolError && e.message.includes(\"timed out\")) {\n    // increase inspect_image.timeoutMs and retry, or check provider latency\n  } else throw e;\n}","preventionTips":["Set inspect_image.timeoutMs generously (60s+) for vision workloads; 0 disables.","Keep images small to reduce upload and inference latency.","Avoid slow/rate-limited providers for the vision role."],"tags":["timeout","network","llm-request"],"backgroundTag":"request-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}