openclaw - ✅(Solved) Fix [Bug]: Per-model `api` override not resolved in auth path [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#80487Fetched 2026-05-11 03:14:09
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
2
Author
Timeline (top)
cross-referenced ×3labeled ×2commented ×1

When a model within a custom provider overrides api (e.g., api: "ollama" on a model under a provider with api: "openai-completions"), the request fails with "No API provider registered for api: ollama". The config schema accepts the override and the streaming path handles it correctly, but the auth resolution path only reads the provider-level api.

Error Message

Error: No API provider registered for api: ollama

Root Cause

Request fails immediately: "No API provider registered for api: ollama". The Ollama plugin's hooks are never discovered because resolveProviderHookRefs in provider-runtime.ts only reads providerConfig.api (provider-level), not the model's effective api.

Fix Action

Fix / Workaround

  • Affected: Users running local routers/proxies that handle multiple backends behind a single provider
  • Severity: Medium: blocks per-model api overrides entirely for plugin-registered APIs (ollama, etc.). Workaround exists (split into separate providers per API type)
  • Frequency: Always, 100% reproducible when per-model api differs from provider-level api for a plugin-registered API
  • Consequence: Users must create separate provider entries for each transport type, fragmenting the model list and complicating configuration

PR fix notes

PR #80488: fix(auth): resolve per-model api override in provider hook refs

Description (problem / solution / changelog)

Summary

  • Problem: When a model within a custom provider overrides api (e.g., api: "ollama" under a provider with api: "openai-completions"), the auth resolution path fails with "No API provider registered for api: ollama" because resolveProviderHookRefs only reads the provider-level providerConfig.api, not the model's effective api.
  • Why it matters: Per-model api overrides are accepted by the config schema and respected by the streaming path (ensureCustomApiRegistered in provider-stream.ts), but the auth path doesn't follow — making the feature partially broken. This blocks a common use case: a local router/proxy with multiple backends behind a single provider, where some models need a different transport protocol.
  • What changed: Added an optional modelApi parameter to resolveProviderHookRefs that takes precedence over providerConfig.api via ?? fallback. Threaded it through resolveProviderSyntheticAuthWithPlugin, shouldDeferProviderSyntheticProfileAuthWithPlugin, resolveProviderSyntheticRuntimeAuth, resolveSyntheticLocalProviderAuth, and resolveApiKeyForProvider.
  • What did NOT change (scope boundary): No changes to streaming, model resolution, provider discovery, or plugin registration. All new parameters are optional — existing callers are unaffected. No config schema changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #80487
  • Related #57099, #57811, #63218
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Per-model api: "ollama" override within a non-ollama provider fails with "No API provider registered for api: ollama".
  • Real environment tested: OpenClaw 2026.5.6 Docker, custom provider routing through a local LLM proxy with mixed openai-completions and ollama models.
  • Exact steps or command run after this patch:
    1. Configure a provider with api: "openai-completions" as default
    2. Add a model with api: "ollama" and baseUrl pointing to a local Ollama instance
    3. Send a chat message using that model
  • Evidence after fix: Code-level verification only — the fix adds modelApi to resolveProviderHookRefs so "ollama" appears in the provider refs when a model overrides api. Unable to build and run a patched OpenClaw locally (@openclaw/fs-safe build toolchain not available on contributor environment).
  • Observed result after fix: Not yet verified at runtime. Requesting maintainer guidance on testing, or verification via CI.
  • What was not tested: Runtime behavior with a patched build. The fix is based on code path analysis — confirmed the exact line where model-level api is dropped (provider-runtime.ts:103).
  • Before evidence: "No API provider registered for api: ollama" confirmed on OpenClaw 2026.5.6 when using per-model api: "ollama" override within a provider configured with api: "openai-completions".

Root Cause

  • Root cause: resolveProviderHookRefs reads providerConfig.api which is the provider-level field. When a model overrides api, the override is resolved at the model level but never passed to the hook resolution function. The Ollama plugin's hooks (synthetic auth, stream creation) are only discovered when "ollama" appears in the provider refs — which it doesn't when the provider itself uses "openai-completions".
  • Missing detection / guardrail: No test covers the case where a model-level api override differs from the provider-level api. The existing synthetic-auth-discovery tests only cover provider-level api configurations.
  • Contributing context: #63218 fixed multi-instance Ollama routing (multiple providers each with api: "ollama"), but that fix operates at the provider level. Per-model overrides are a distinct code path that wasn't addressed.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/model-auth.test.ts
  • Scenario the test should lock in: resolveApiKeyForProvider with a custom provider using api: "openai-completions" at provider level and modelApi: "ollama" passed as override — should resolve via the Ollama plugin's synthetic auth, not fail with "No API provider registered".
  • Why this is the smallest reliable guardrail: Tests the exact junction point where provider-level and model-level api diverge in the auth resolution chain.
  • Existing test that already covers this: None — existing tests in model-auth.test.ts only cover provider-level api: "ollama" configurations.
  • If no new test is added, why not: Contributor does not have the full build toolchain for @openclaw/fs-safe to run tests locally. Happy to add the test if a maintainer can advise on the local test setup, or if a maintainer prefers to add it during review.

User-visible / Behavior Changes

Models with per-model api overrides (e.g., api: "ollama" within an openai-completions provider) now correctly resolve authentication through the overridden API's plugin hooks. Previously these models failed immediately with "No API provider registered".

Diagram

Before:
  model.api = "ollama" (override)
    → resolveProviderHookRefs(provider, providerConfig)
    → reads providerConfig.api = "openai-completions"
    → refs = ["my-router", "openai-completions"]
    → ollama plugin NOT found → auth fails

After:
  model.api = "ollama" (override)
    → resolveProviderHookRefs(provider, providerConfig, modelApi="ollama")
    → reads modelApi ?? providerConfig.api = "ollama"
    → refs = ["my-router", "ollama"]
    → ollama plugin FOUND → synthetic auth resolves

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No — same auth resolution logic, just broader discovery scope
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux (Docker)
  • Runtime/container: OpenClaw 2026.5.6
  • Model/provider: Custom provider with api: "openai-completions", model override api: "ollama"
  • Integration/channel: Telegram (group chat)
  • Relevant config (redacted):
{
  models: {
    providers: {
      "my-router": {
        baseUrl: "http://localhost:8080/v1",
        api: "openai-completions",
        models: [
          { id: "my-router/cloud-model", name: "Cloud Model" },
          { id: "my-router/local-llama", name: "Local Llama", api: "ollama", baseUrl: "http://localhost:11434" }
        ]
      }
    }
  }
}

Steps

  1. Set primary model to my-router/local-llama
  2. Send a chat message
  3. Observe auth resolution

Expected

  • Model resolves synthetic Ollama auth and responds

Actual (before fix)

  • "No API provider registered for api: ollama"

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers

Before: Error: No API provider registered for api: ollama on every request to the model with api: "ollama" override. Confirmed on OpenClaw 2026.5.6.

After: Not yet verified at runtime — code-level analysis only. CI should validate.

Human Verification

  • Verified scenarios: Code path analysis — traced resolveProviderHookRefsresolveProviderSyntheticAuthWithPluginresolveApiKeyForProvider and confirmed the model-level api is never included in hook refs without this fix. Verified existing callers are unaffected (all new params are optional with ?? fallback).
  • Edge cases checked (code-level): Provider with no api field (defaults) — modelApi ?? undefined falls through, no change. Provider with api: "ollama" at provider level — modelApi ?? "ollama" produces same result. Model without api override — modelApi not passed, existing behavior preserved.
  • What you did not verify: Runtime behavior with a patched build. Could not run tests locally due to missing @openclaw/fs-safe build toolchain. Relying on CI for validation.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes — all new parameters are optional
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: A model-level api override could cause the auth resolver to discover an unexpected plugin if the api string matches a plugin the user didn't intend.
    • Mitigation: The modelApi parameter is only used when explicitly passed by the caller — existing code paths without modelApi behave identically. The ?? fallback ensures provider-level api is still the default.

Changed files

  • src/agents/model-auth.test.ts (modified, +37/-0)
  • src/agents/model-auth.ts (modified, +5/-1)
  • src/plugins/provider-runtime.ts (modified, +6/-4)

Code Example

{
  models: {
    providers: {
      "my-router": {
        baseUrl: "http://localhost:8080/v1",
        api: "openai-completions",
        models: [
          { id: "my-router/local-llama", name: "Local Llama", api: "ollama", baseUrl: "http://localhost:11434" }
        ]
      }
    }
  },
  plugins: { allow: ["ollama"] }
}

---

Error: No API provider registered for api: ollama
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When a model within a custom provider overrides api (e.g., api: "ollama" on a model under a provider with api: "openai-completions"), the request fails with "No API provider registered for api: ollama". The config schema accepts the override and the streaming path handles it correctly, but the auth resolution path only reads the provider-level api.

Steps to reproduce

  1. Configure a custom provider with api: "openai-completions" and add a model with api: "ollama" override:
{
  models: {
    providers: {
      "my-router": {
        baseUrl: "http://localhost:8080/v1",
        api: "openai-completions",
        models: [
          { id: "my-router/local-llama", name: "Local Llama", api: "ollama", baseUrl: "http://localhost:11434" }
        ]
      }
    }
  },
  plugins: { allow: ["ollama"] }
}
  1. Set primary model to my-router/local-llama
  2. Send a chat message

Expected behavior

Model resolves auth via the Ollama plugin's synthetic auth hook (same as when api: "ollama" is set at provider level) and responds normally.

Actual behavior

Request fails immediately: "No API provider registered for api: ollama". The Ollama plugin's hooks are never discovered because resolveProviderHookRefs in provider-runtime.ts only reads providerConfig.api (provider-level), not the model's effective api.

OpenClaw version

2026.5.6

Operating system

Ubuntu 24.04

Install method

docker

Model

Custom provider model with per-model api: "ollama" override

Provider / routing chain

openclaw → custom local router → local Ollama instance / openai model

Additional provider/model setup details

The use case is a local LLM router that proxies multiple backends behind a single provider entry. Most models use openai-completions transport, but some local models need ollama. The ollama plugin is enabled in plugins.allow. Provider-level api: "ollama" works fine (as fixed in #63218) the issue is specifically with per-model api overrides within a non-ollama provider.

Logs, screenshots, and evidence

Error: No API provider registered for api: ollama

Impact and severity

  • Affected: Users running local routers/proxies that handle multiple backends behind a single provider
  • Severity: Medium: blocks per-model api overrides entirely for plugin-registered APIs (ollama, etc.). Workaround exists (split into separate providers per API type)
  • Frequency: Always, 100% reproducible when per-model api differs from provider-level api for a plugin-registered API
  • Consequence: Users must create separate provider entries for each transport type, fragmenting the model list and complicating configuration

Additional information

  • Provider-level api: "ollama" works correctly since #63218 that fix addressed multi-instance routing (multiple providers each with api: "ollama"). Per-model overrides are a distinct code path that wasn't covered.
  • The config schema and inline-provider resolution (model.inline-provider.ts) both accept per-model api overrides. The streaming path respects them. Only the auth resolution path is missing.
  • Related: #57099, #57811, #63218

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Model resolves auth via the Ollama plugin's synthetic auth hook (same as when api: "ollama" is set at provider level) and responds normally.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Per-model `api` override not resolved in auth path [1 pull requests, 1 comments, 2 participants]