Skip to content

[Bug]: image tool fails with custom provider — ModelRegistry doesn't recognize custom providers from models.json #65832

@GentleCold

Description

@GentleCold

Bug type

Behavior bug (incorrect output/state without crash)

Summary

The image tool throws Unknown model: <custom-provider>/<model-id> when imageModel is configured with a custom provider defined in models.json, because the tool internally uses @mariozechner/pi-coding-agent's ModelRegistry.find() which does not properly load custom providers from models.json.

Steps to reproduce

  1. Configure a custom OpenAI-compatible proxy provider in openclaw.json under models.providers with baseUrl, apiKey, api, and models array.
  2. Set agents.defaults.imageModel to custom-provider/model-id (where custom-provider is not a built-in pi-ai provider).
  3. Send an image to the agent (e.g., via Feishu or other channel).
  4. The image tool is invoked and fails with Unknown model: custom-provider/model-id.

Expected behavior

The image tool should resolve custom providers from models.json the same way the main runner does, allowing imageModel to point to models on custom providers.

Observed behavior

The image tool fails with Unknown model error. Two specific root causes identified:

Root Cause 1: Validation failure in models.json blocks all custom model loading

If ANY provider in models.json has a models array but no apiKey (e.g., a provider auto-generated by ensureOpenClawModelsJson that uses OAuth-only auth), ModelRegistry.validateConfig throws, causing loadCustomModels to return an error result. This makes the ENTIRE custom models + overrides loading fail — including provider-level baseUrl overrides for OTHER built-in providers.

// ModelRegistry.validateConfig throws:
// "Provider xxx: apiKey is required when defining custom models."
// → loadCustomModels returns emptyCustomModelsResult({ error })
// → overrides Map is empty
// → loadBuiltInModels doesn't apply baseUrl overrides from models.json

Root Cause 2: Custom providers not in built-in catalog are invisible to image tool

Even without the validation error, providers that don't exist in pi-ai's built-in MODELS catalog are not found by registry.find(). The mergeCustomModels method does add them to this.models, but only when loadCustomModels succeeds without error. The main runner resolves models through a different path that handles custom providers correctly.

OpenClaw version

2026.4.11

Operating system

Linux (Ubuntu, kernel 6.8.0-65-generic, x64)

Model

custom-proxy/zai-org/glm-5.1 (primary, works in main chat)
custom-proxy/zai-org/glm-5v-turbo (imageModel, fails in image tool)

Provider / routing chain

openclaw -> custom OpenAI-compatible proxy -> upstream model provider

Additional provider/model setup details

Custom provider is configured in openclaw.json under models.providers with baseUrl, apiKey: "...", api: "openai-completions", and a models array containing the vision model with input: ["text", "image"]. The same custom provider works correctly for the primary text model in main chat. Only the image tool fails because it uses PiCodingAgent.ModelRegistry.find() which has limited custom provider support.

Logs, screenshots, and evidence

Error: Unknown model: custom-proxy/zai-org/glm-5v-turbo

Source: image-CDit-npy.js line 24:

const model = modelRegistry.find(resolvedRef.provider, resolvedRef.model);
if (!model) throw new Error(`Unknown model: ${resolvedRef.provider}/${resolvedRef.model}`);

When attempting to use a built-in provider name (e.g., zai/glm-5v-turbo) as imageModel with a baseUrl override in models.json for the zai provider, the override is not applied because loadCustomModels fails due to an unrelated validation error in another provider (see Root Cause 1). The model resolves with the built-in baseUrl instead of the override, resulting in a 401 error.

Impact and severity

  • Affected: Users with custom proxy providers (OpenAI-compatible) who want to use a vision model via the image tool
  • Severity: Medium (blocks image tool for custom providers, workaround exists)
  • Frequency: Always (deterministic, every image tool invocation fails)
  • Consequence: Images cannot be analyzed using dedicated vision models; must fall back to primary model via read tool, which may have inferior vision capabilities

Additional information

Workaround: Images can be analyzed by using the read tool to send the image content to the primary text model, which resolves custom providers through its own model resolution path. The image tool specifically cannot use custom providers.

Suggested fixes:

  1. Make loadCustomModels more resilient — a validation error for one provider should not prevent loading other providers and overrides.
  2. Ensure ensureOpenClawModelsJson does not generate providers with models arrays but no apiKey when the provider uses OAuth.
  3. Consider having the image tool use the same model resolution path as the main runner, which correctly handles custom providers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clawsweeperTracked by ClawSweeper automation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions