openclaw - ✅(Solved) Fix [cron] Model override rejected despite being in agents.defaults.models allowlist (provider prefix normalization mismatch) [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#77234Fetched 2026-05-05 05:50:52
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Timeline (top)
commented ×1cross-referenced ×1

When a cron job specifies a model override like model: "openrouter/arcee-ai/trinity-large-preview:free", the job is rejected with "cron payload.model arcee-ai/trinity-large-preview:free rejected by agents.defaults.models allowlist" — even though the model is explicitly present in agents.defaults.models.

Error Message

  1. Job fires \u2192 immediately rejected with the allowlist error above

Root Cause

The issue is a provider prefix normalization mismatch between how the model key is stored when a cron job is created vs. how the allowlist keys are built when checking the model.

  • Config file (agents.defaults.models): Key stored as "openrouter/arcee-ai/trinity-large-preview:free"
  • Cron payload model override: Stored internally as "arcee-ai/trinity-large-preview:free" (provider prefix stripped during cron API processing)
  • Allowlist key builder (buildAllowedModelSetWithFallbacks \u2192 resolveAllowlistModelKey): Uses the full "openrouter/arcee-ai/trinity-large-preview:free" form

Result: the allowlist has openrouter/arcee-ai/trinity-large-preview:free, but the check looks for arcee-ai/trinity-large-preview:free — no match.

Fix Action

Fixed

PR fix notes

PR #77240: fix(agents): resolve providerless configured cron models

Description (problem / solution / changelog)

Summary

  • Problem: cron payload.model overrides could be checked after a provider prefix was stripped, e.g. arcee-ai/trinity-large-preview:free, while the allowlist only contained openrouter/arcee-ai/trinity-large-preview:free.
  • Why it matters: configured OpenRouter models in agents.defaults.models were rejected when used by cron despite being explicitly allowed.
  • What changed: when the first parse is not allowed, model selection now infers a unique provider from configured models using the full raw model id, then re-checks that inferred provider/model key.
  • What did NOT change (scope boundary): no changes to cron storage, model catalog loading, aliases, fallback ordering, or provider auth behavior.

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 #77234
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: provider/model parsing treated a provider-less nested OpenRouter model id as if its first path segment were the provider before allowlist checking.
  • Missing detection / guardrail: resolver coverage did not include a configured openrouter/<nested-model> allowlist entry checked against the same nested model id without the provider prefix.
  • Contributing context (if known): cron model override storage can preserve the model id separately from provider identity.

Regression Test Plan (if applicable)

  • 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-selection-resolve.test.ts
  • Scenario the test should lock in: arcee-ai/trinity-large-preview:free resolves to the configured openrouter/arcee-ai/trinity-large-preview:free allowlist key.
  • Why this is the smallest reliable guardrail: the bug is in shared model selection/allowlist resolution before cron executes a turn.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Cron jobs whose OpenRouter model override is checked without the provider prefix now pass the configured agents.defaults.models allowlist when that nested model id uniquely belongs to OpenRouter.

Diagram (if applicable)

Before:
payload.model arcee-ai/trinity-large-preview:free -> parsed as arcee-ai/trinity-large-preview:free -> allowlist miss

After:
payload.model arcee-ai/trinity-large-preview:free -> infer openrouter from configured models -> openrouter/arcee-ai/trinity-large-preview:free -> allowed

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: Debian 13 container
  • Runtime/container: Node v20.19.2 locally (repo warns it wants Node >=22.14.0)
  • Model/provider: OpenRouter model-selection fixture
  • Integration/channel (if any): cron isolated agent model selection
  • Relevant config (redacted): agents.defaults.models["openrouter/arcee-ai/trinity-large-preview:free"]

Steps

  1. Configure agents.defaults.models with openrouter/arcee-ai/trinity-large-preview:free.
  2. Resolve cron-style payload model arcee-ai/trinity-large-preview:free through resolveAllowedModelRef.
  3. Check the returned allowlist key.

Expected

  • The model resolves to provider openrouter and key openrouter/arcee-ai/trinity-large-preview:free.

Actual

  • Before this patch, the model resolved as provider arcee-ai and was rejected as not allowed.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • pnpm test src/agents/model-selection-resolve.test.ts src/cron/isolated-agent.model-formatting.test.ts
    • pnpm exec oxfmt --check --threads=1 src/agents/model-selection-shared.ts src/agents/model-selection-resolve.test.ts CHANGELOG.md
    • git diff --check
  • Edge cases checked: existing OpenRouter compat alias tests, proxy provider id test, and cron model-formatting tests still pass.
  • What you did not verify: full pnpm check:changed remains blocked by an unrelated current-main core-test type error in src/agents/model-auth.profiles.test.ts:48 under this local Node v20.19.2 environment.

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/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: provider inference could accidentally allow an ambiguous nested model id.
    • Mitigation: the fallback only runs when the configured-model scan finds exactly one provider and the inferred provider/model still passes the existing allowlist status check.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/model-selection-resolve.test.ts (modified, +25/-0)
  • src/agents/model-selection-shared.ts (modified, +15/-3)

Code Example

"agents": {
     "defaults": {
       "models": {
         "openrouter/arcee-ai/trinity-large-preview:free": {}
       },
       "model": {
         "fallbacks": ["openrouter/arcee-ai/trinity-large-preview:free"]
       }
     }
   }
RAW_BUFFERClick to expand / collapse

Summary

When a cron job specifies a model override like model: "openrouter/arcee-ai/trinity-large-preview:free", the job is rejected with "cron payload.model arcee-ai/trinity-large-preview:free rejected by agents.defaults.models allowlist" — even though the model is explicitly present in agents.defaults.models.

Root Cause

The issue is a provider prefix normalization mismatch between how the model key is stored when a cron job is created vs. how the allowlist keys are built when checking the model.

  • Config file (agents.defaults.models): Key stored as "openrouter/arcee-ai/trinity-large-preview:free"
  • Cron payload model override: Stored internally as "arcee-ai/trinity-large-preview:free" (provider prefix stripped during cron API processing)
  • Allowlist key builder (buildAllowedModelSetWithFallbacks \u2192 resolveAllowlistModelKey): Uses the full "openrouter/arcee-ai/trinity-large-preview:free" form

Result: the allowlist has openrouter/arcee-ai/trinity-large-preview:free, but the check looks for arcee-ai/trinity-large-preview:free — no match.

Contradiction

The same model works perfectly as a fallback (in agents.defaults.model.fallbacks) because that path uses raw string comparison of the config values, not key-based lookup. The model only fails when used as an explicit cron payload override.

Reproduction

  1. Add model to agents.defaults.models:
    "agents": {
      "defaults": {
        "models": {
          "openrouter/arcee-ai/trinity-large-preview:free": {}
        },
        "model": {
          "fallbacks": ["openrouter/arcee-ai/trinity-large-preview:free"]
        }
      }
    }
  2. Create a cron job with model: "openrouter/arcee-ai/trinity-large-preview:free" via the cron API
  3. Job fires \u2192 immediately rejected with the allowlist error above

Suggested Fix

Normalize the model key consistently at cron store time (when the model override is saved from the cron API payload) so it matches the normalized form that resolveAllowlistModelKey produces at check time. Alternatively, fix the allowlist key builder to handle both forms.

Version

OpenClaw v2026.5.3

extent analysis

TL;DR

Normalize the model key consistently at cron store time to match the allowlist key builder's expected format.

Guidance

  • Verify that the agents.defaults.models configuration contains the model key with the provider prefix, e.g., "openrouter/arcee-ai/trinity-large-preview:free".
  • Update the cron API processing to store the model override with the full key, including the provider prefix, to match the allowlist key builder's expectations.
  • Consider adding a normalization step in the allowlist key builder to handle both forms of the model key, with and without the provider prefix.
  • Test the fix by recreating the cron job with the updated model override and verifying that it is no longer rejected by the allowlist check.

Example

No code snippet is provided as the issue is related to configuration and key normalization, and the suggested fix involves updating the cron API processing or allowlist key builder.

Notes

The fix may require updates to the cron API or the allowlist key builder, and careful testing is necessary to ensure that the normalization is correct and consistent.

Recommendation

Apply workaround: Update the cron API processing to store the model override with the full key, including the provider prefix, to match the allowlist key builder's expectations, as this is a more targeted fix that can be implemented without modifying the allowlist key builder.

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

openclaw - ✅(Solved) Fix [cron] Model override rejected despite being in agents.defaults.models allowlist (provider prefix normalization mismatch) [1 pull requests, 1 comments, 2 participants]