{"record":{"id":"dd38d1ddd55b1d22","repo":"can1357/oh-my-pi","slug":"unable-to-resolve-a-model-for-inspect-image","errorCode":null,"errorMessage":"Unable to resolve a model for inspect_image.","messagePattern":"Unable to resolve a model for inspect_image\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/inspect-image.ts","lineNumber":195,"sourceCode":"\t\tconst activeModelPattern = this.session.getActiveModelString?.() ?? this.session.getModelString?.();\n\t\tlet model: Model<Api> | undefined;\n\t\tlet selectedPattern: string | undefined;\n\t\tfor (const pattern of [\"@vision\", \"@default\", activeModelPattern]) {\n\t\t\tconst resolved = resolvePattern(pattern);\n\t\t\tif (resolved?.input.includes(\"image\")) {\n\t\t\t\tmodel = resolved;\n\t\t\t\tselectedPattern = pattern;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tconst activeProvider = resolvePattern(activeModelPattern)?.provider;\n\t\tmodel ??= availableModels.find(\n\t\t\tcandidate => candidate.provider === activeProvider && candidate.input.includes(\"image\"),\n\t\t);\n\t\tmodel ??= availableModels.find(candidate => candidate.input.includes(\"image\"));\n\t\tif (!model) {\n\t\t\tconst textOnly = resolvePattern(\"@vision\") ?? resolvePattern(\"@default\") ?? resolvePattern(activeModelPattern);\n\t\t\tif (!textOnly) throw new ToolError(\"Unable to resolve a model for inspect_image.\");\n\t\t\tthrow new ToolError(\n\t\t\t\t`Resolved model ${textOnly.provider}/${textOnly.id} does not support image input. Configure a vision-capable model for modelRoles.vision.`,\n\t\t\t);\n\t\t}\n\n\t\tconst apiKey = await modelRegistry.getApiKey(model);\n\t\tif (!apiKey) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`No API key available for ${model.provider}/${model.id}. Configure credentials for this provider or choose another vision-capable model.`,\n\t\t\t);\n\t\t}\n\n\t\tlet imageInput: LoadedImageInput | null;\n\t\tconst autoResize = this.session.settings.get(\"images.autoResize\");\n\t\tconst excludeWebP = webpExclusionForModel(model);\n\t\tconst attachmentReference = parseImageAttachmentReference(params.path);\n\t\tconst imageTarget = attachmentReference\n\t\t\t? undefined","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/inspect-image.ts#L177-L213","documentation":"inspect_image first tries to find a model whose declared input modalities include \"image\" (via roles @vision/@default, the active model, same-provider candidates, then any candidate). If no image-capable model exists at all but a text-only model can be resolved, it throws this error. The variant thrown here fires when not even a text-only model could be resolved from @vision, @default, or the active model pattern — i.e. the pattern strings match nothing in the registry.","triggerScenarios":"No available model has \"image\" in its input modalities AND resolvePattern fails for @vision, @default, and the active model string — e.g. role aliases unconfigured, the active model id not present in the registry, or the registry contents not matching config.","commonSituations":"Configured modelRoles.vision points to a model id that isn't registered; the active model was set to an id that failed discovery; a custom registry/allowlist filtered out every known model.","solutions":["Configure modelRoles.vision in settings to a registered, vision-capable model (e.g. provider/model-id).","Verify the model ids in your config exactly match what the registry lists.","Add/enable a vision-capable provider so getAvailable() includes an image-input model.","Check for typos in role aliases (@vision/@default) and custom model filters."],"exampleFix":"// before (settings)\n{ \"modelRoles\": {} }\n// after\n{ \"modelRoles\": { \"vision\": \"openai/gpt-4o\" } }","handlingStrategy":"validation","validationCode":"const available = session.modelRegistry.getAvailable();\nconst visionRole = session.settings.get(\"modelRoles.vision\");\nconst resolved = available.some(m =>\n  visionRole ? `${m.provider}/${m.id}` === String(visionRole).split(\":\")[0] : m.input.includes(\"image\")\n);\nif (!resolved) {\n  // fix modelRoles.vision or register a vision model before calling inspect_image\n}","typeGuard":null,"tryCatchPattern":"try {\n  await inspectImageTool.execute(id, params, signal);\n} catch (e) {\n  if (e instanceof ToolError && e.message.includes(\"Unable to resolve a model\")) {\n    // correct modelRoles.vision / active model configuration\n  } else throw e;\n}","preventionTips":["Keep modelRoles.vision pointing at exact ids that exist in the registry.","After changing model allowlists/filters, re-verify role resolution.","Prefer resolving roles through the same resolver the tool uses (expandRoleAlias + resolveModelFromString) in pre-checks."],"tags":["configuration","models","model-resolution"],"backgroundTag":"model-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}