openclaw - 💡(How to fix) Fix Plugin-SDK `DEFAULT_PROVIDER` hardcoded to "openai" breaks plugin model resolution for users on `openai-codex`-only setups [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#71659Fetched 2026-04-26 05:10:11
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
0
Timeline (top)
closed ×1commented ×1subscribed ×1

Root Cause

DEFAULT_PROVIDER is a compile-time constant:

// dist/defaults-DM8yIn8C.js
const DEFAULT_PROVIDER = "openai";
const DEFAULT_MODEL = "gpt-5.5";
const DEFAULT_CONTEXT_TOKENS = 2e5;

Type signature:

// packages/plugin-sdk/dist/src/agents/defaults.d.ts
export declare const DEFAULT_PROVIDER = "openai";

Consumed by ~10 modules including plugin code:

// extensions/active-memory/index.ts
import { DEFAULT_PROVIDER, parseModelRef, ... } from "openclaw/plugin-sdk/agent-runtime";

function parseModelCandidate(modelRef) {
  if (!modelRef) return undefined;
  return (
    parseModelRef(modelRef, DEFAULT_PROVIDER) ??
    { provider: DEFAULT_PROVIDER, model: modelRef }
  );
}

parseModelRef (in dist/model-selection-shared-CGq2vKNt.js) only uses defaultProvider when the input has no / separator. So a user who passes a bare "gpt-5.5" (or whose plugin-resolved model is bare) ends up with openai/gpt-5.5 regardless of what providers are actually configured.

Fix Action

Fix / Workaround

  • active-memory (recall lookups)
  • skill-workshop (reviewer agent — workaround: set reviewMode: "heuristic" to bypass the LLM path)
  • llm-slug-generator

Workaround: every affected plugin's user-facing config must include an explicit model: "openai-codex/gpt-5.5" (or similar) field. Plugins without such a field (e.g., earlier skill-workshop revisions) have no recourse other than disabling the LLM path.

Code Example

// ~/.openclaw/openclaw.json
{
  "agents": {
    "defaults": {
      "model": { "provider": "openai-codex", "id": "gpt-5.5" }
    }
  },
  "auth": {
    "profiles": {
      "openai-codex:default": { "type": "oauth" /* Codex Pro */ }
    }
  }
  // NO "openai" provider configured anywhere
}

---

// dist/defaults-DM8yIn8C.js
const DEFAULT_PROVIDER = "openai";
const DEFAULT_MODEL = "gpt-5.5";
const DEFAULT_CONTEXT_TOKENS = 2e5;

---

// packages/plugin-sdk/dist/src/agents/defaults.d.ts
export declare const DEFAULT_PROVIDER = "openai";

---

// extensions/active-memory/index.ts
import { DEFAULT_PROVIDER, parseModelRef, ... } from "openclaw/plugin-sdk/agent-runtime";

function parseModelCandidate(modelRef) {
  if (!modelRef) return undefined;
  return (
    parseModelRef(modelRef, DEFAULT_PROVIDER) ??
    { provider: DEFAULT_PROVIDER, model: modelRef }
  );
}

---

export function resolveDefaultProvider(cfg: OpenClawConfig): string {
  return cfg.agents?.defaults?.model?.provider ?? "openai";
}
RAW_BUFFERClick to expand / collapse

Problem

DEFAULT_PROVIDER is exported from the plugin-SDK as a hardcoded string "openai". Plugins import this constant and use it as the fallback provider when parsing user-provided model refs (e.g., parseModelRef("gpt-5.5", DEFAULT_PROVIDER)).

For users on a Codex Pro OAuth setup (where the only configured provider is openai-codex, with no openai provider), the plugin-resolved model ref becomes openai/<model>, which fails downstream because openai isn't configured. There's no fallback to the user's actual configured providers.

Three bundled plugins are affected on a typical install:

  • active-memory (recall lookups)
  • skill-workshop (reviewer agent — workaround: set reviewMode: "heuristic" to bypass the LLM path)
  • llm-slug-generator

Repro

Setup:

// ~/.openclaw/openclaw.json
{
  "agents": {
    "defaults": {
      "model": { "provider": "openai-codex", "id": "gpt-5.5" }
    }
  },
  "auth": {
    "profiles": {
      "openai-codex:default": { "type": "oauth" /* Codex Pro */ }
    }
  }
  // NO "openai" provider configured anywhere
}

Enable active-memory with default config (no model override). Send a DM that should trigger recall.

Observed: active-memory resolves model ref to openai/gpt-5.5 (or whatever the user's config returns through getModelRef paths) and the LLM call fails because the openai provider has no auth profile.

Workaround: every affected plugin's user-facing config must include an explicit model: "openai-codex/gpt-5.5" (or similar) field. Plugins without such a field (e.g., earlier skill-workshop revisions) have no recourse other than disabling the LLM path.

Root cause

DEFAULT_PROVIDER is a compile-time constant:

// dist/defaults-DM8yIn8C.js
const DEFAULT_PROVIDER = "openai";
const DEFAULT_MODEL = "gpt-5.5";
const DEFAULT_CONTEXT_TOKENS = 2e5;

Type signature:

// packages/plugin-sdk/dist/src/agents/defaults.d.ts
export declare const DEFAULT_PROVIDER = "openai";

Consumed by ~10 modules including plugin code:

// extensions/active-memory/index.ts
import { DEFAULT_PROVIDER, parseModelRef, ... } from "openclaw/plugin-sdk/agent-runtime";

function parseModelCandidate(modelRef) {
  if (!modelRef) return undefined;
  return (
    parseModelRef(modelRef, DEFAULT_PROVIDER) ??
    { provider: DEFAULT_PROVIDER, model: modelRef }
  );
}

parseModelRef (in dist/model-selection-shared-CGq2vKNt.js) only uses defaultProvider when the input has no / separator. So a user who passes a bare "gpt-5.5" (or whose plugin-resolved model is bare) ends up with openai/gpt-5.5 regardless of what providers are actually configured.

Proposed fix

Three options, in increasing scope:

Option A: Make DEFAULT_PROVIDER resolve from runtime config

Replace the constant with a function that reads agents.defaults.model.provider first, and only falls back to "openai" if nothing is configured:

export function resolveDefaultProvider(cfg: OpenClawConfig): string {
  return cfg.agents?.defaults?.model?.provider ?? "openai";
}

Plugins call api.runtime.resolveDefaultProvider() (or similar) instead of importing the constant. Backwards-compatible if the constant is kept as a fallback for plugins that haven't migrated.

Option B: Have parseModelRef consult configured providers

When the input is bare (no /), and the supplied defaultProvider isn't actually configured, fall through to the first configured provider (or the agent's primary). This silently fixes existing plugin code without requiring migration.

Option C: Plugin-SDK opinion: require explicit model in plugin config

Document that any plugin invoking an LLM must accept a user-provided model field, validate it against configured providers at config-load time, and reject the plugin enable if no usable provider is available. This is the most invasive but the most correct.

Impact

Anyone running OpenClaw against openai-codex OAuth (Codex Pro / ChatGPT subscription) without also configuring an openai API key hits this on active-memory, skill-workshop LLM reviewer, and llm-slug-generator. The failure mode is a stack trace in the gateway logs and the plugin path silently doing nothing user-visible (active-memory recall returns empty; skill-workshop reviewer noops).

Same impact applies to Anthropic-only setups using claude-cli or ACP backends, since openai likewise isn't configured.

Environment

  • OpenClaw: 2026.4.24 (028b6c9)
  • Symbol confirmed in current dist:
    • dist/defaults-DM8yIn8C.js:2
    • packages/plugin-sdk/dist/src/agents/defaults.d.ts
    • extensions/active-memory/index.ts (consumer)
  • Reproducible setup: openai-codex OAuth (Codex Pro), no openai API key, default agents.defaults.model.provider: openai-codex.

extent analysis

TL;DR

The most likely fix is to replace the hardcoded DEFAULT_PROVIDER constant with a function that resolves the default provider from the runtime configuration.

Guidance

  • Identify the affected plugins (active-memory, skill-workshop, and llm-slug-generator) and consider applying a workaround by setting an explicit model field in their configurations.
  • Review the proposed fix options (A, B, or C) and choose the one that best fits the use case, considering factors such as backwards compatibility and plugin migration requirements.
  • If opting for Option A, update the DEFAULT_PROVIDER constant to a function that reads the agents.defaults.model.provider configuration and falls back to "openai" if necessary.
  • Test the fix by setting up a reproducible environment with OpenClaw and verifying that the affected plugins resolve the model reference correctly.

Example

export function resolveDefaultProvider(cfg: OpenClawConfig): string {
  return cfg.agents?.defaults?.model?.provider ?? "openai";
}

This example illustrates the proposed fix for Option A, where the DEFAULT_PROVIDER constant is replaced with a function that resolves the default provider from the runtime configuration.

Notes

The fix may require updates to the plugin code and configuration, and it's essential to test the changes thoroughly to ensure that the affected plugins work correctly with the new default provider resolution mechanism.

Recommendation

Apply workaround by setting an explicit model field in the configurations of the affected plugins, as this is the most straightforward solution that doesn't require significant code changes.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING