openclaw - 💡(How to fix) Fix [Bug]: cron preflight normalizes LiteLLM-backed Gemini model allowlist entries to Google preview IDs

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…

After upgrading from OpenClaw 2026.5.7 to 2026.5.18, cron agentTurn payloads using a configured non-Google provider model such as litellm/gemini-3-flash are rejected by cron preflight because the runtime allowlist is normalized to litellm/gemini-3-flash-preview.

Error Message

Cron then rejects the original payload model in src/cron/isolated-agent/model-selection.ts via resolveAllowedModelRef() / allowlist validation, producing the observed cron payload.model ... rejected by agents.defaults.models allowlist error.

Root Cause

Summary

After upgrading from OpenClaw 2026.5.7 to 2026.5.18, cron agentTurn payloads using a configured non-Google provider model such as litellm/gemini-3-flash are rejected by cron preflight because the runtime allowlist is normalized to litellm/gemini-3-flash-preview.

Fix Action

Fix / Workaround

The issue is not that the provider cannot serve the model. The failure happens before dispatch, during cron model allowlist/preflight validation.

Severity: High for affected installations because scheduled jobs fail before model dispatch.

Additional information

Temporary workaround: migrate affected cron payloads away from litellm/gemini-3-flash to a non-affected configured model such as litellm/minimax-m2.5-aws or another model id that does not trigger Gemini preview normalization.

Code Example

{
  "models": {
    "providers": {
      "litellm": {
        "api": "openai-completions",
        "models": [
          { "id": "gemini-3-flash", "name": "Gemini 3 Flash" },
          { "id": "gemini-3.1-pro", "name": "Gemini 3.1 Pro" }
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "models": {
        "litellm/gemini-3-flash": {},
        "litellm/gemini-3.1-pro": {}
      }
    }
  }
}

---

cron payload.model 'litellm/gemini-3-flash' rejected by agents.defaults.models allowlist:
litellm/gemini-3-flash is not in [..., litellm/gemini-3-flash-preview, litellm/gemini-3.1-pro-preview, ...]

---

const provider = normalizeProviderId(trimmed.slice(0, slash));
const normalizedModel = normalizeGooglePreviewModelId(trimmed.slice(slash + 1));
return modelKeyForConfig(provider, normalizedModel);
RAW_BUFFERClick to expand / collapse

Triage note

This report is intentionally structured for automated/model triage: the reproduction is deterministic, the observed/expected behavior is explicit, and the suspected code path is called out separately from the observed evidence.

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After upgrading from OpenClaw 2026.5.7 to 2026.5.18, cron agentTurn payloads using a configured non-Google provider model such as litellm/gemini-3-flash are rejected by cron preflight because the runtime allowlist is normalized to litellm/gemini-3-flash-preview.

Steps to reproduce

  1. Configure a custom/provider-backed model catalog entry under a non-Google LiteLLM-backed provider, for example models.providers.litellm.models[].id = "gemini-3-flash".
  2. Add the same model to agents.defaults.models as litellm/gemini-3-flash.
  3. Create a cron job with sessionTarget = "isolated" and payload.kind = "agentTurn", setting payload.model = "litellm/gemini-3-flash".
  4. Force-run the cron job.
  5. Observe cron preflight rejecting the payload model because the effective allowlist contains litellm/gemini-3-flash-preview instead of litellm/gemini-3-flash.

Expected behavior

A cron payload model should be accepted when it exactly matches a configured provider catalog entry and an agents.defaults.models allowlist entry for that same provider/model key.

In the observed setup, litellm/gemini-3-flash should remain litellm/gemini-3-flash because the configured provider is a custom LiteLLM-backed OpenAI-compatible provider. Google preview model-id normalization should not rewrite the model id unless the provider is Google/Google Gemini CLI/Google Vertex, or the configured provider explicitly opts into such normalization.

Actual behavior

On OpenClaw 2026.5.18, a delivery-none smoke cron using payload.model = "litellm/gemini-3-flash" failed at preflight. The diagnostic reported that litellm/gemini-3-flash was not in the allowlist, while the effective allowlist contained litellm/gemini-3-flash-preview and litellm/gemini-3.1-pro-preview.

This also affected real cron jobs that used litellm/gemini-3-flash as their payload model. Rolling back to OpenClaw 2026.5.7 made the same cron jobs run successfully without changing the cron jobs or the source config.

OpenClaw version

First known bad: 2026.5.12 / 2026.5.13 family; reproduced again on 2026.5.18.

Last known good: 2026.5.7.

Operating system

Linux 6.12.68+ x64, container/GKE-style runtime.

Install method

Containerized OpenClaw gateway runtime.

Model

litellm/gemini-3-flash as cron payload.model.

Provider / routing chain

OpenClaw cron isolated agent -> custom LiteLLM-backed provider -> OpenAI-compatible completions endpoint.

Additional provider/model setup details

Relevant source config uses non-preview model ids:

{
  "models": {
    "providers": {
      "litellm": {
        "api": "openai-completions",
        "models": [
          { "id": "gemini-3-flash", "name": "Gemini 3 Flash" },
          { "id": "gemini-3.1-pro", "name": "Gemini 3.1 Pro" }
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "models": {
        "litellm/gemini-3-flash": {},
        "litellm/gemini-3.1-pro": {}
      }
    }
  }
}

The issue is not that the provider cannot serve the model. The failure happens before dispatch, during cron model allowlist/preflight validation.

Logs, screenshots, and evidence

Observed timeline:

  • On 2026.5.12/2026.5.13, source config and cron payloads both used non-preview litellm/gemini-3-flash, but runtime cron preflight rejected payload.model = "litellm/gemini-3-flash" because the effective allowlist contained preview-normalized entries such as litellm/gemini-3-flash-preview and litellm/gemini-3.1-pro-preview.
  • Rolling back to 2026.5.7 resolved the same cron jobs without changing cron/openclaw.json.
  • On 2026.5.18, the regression reproduced again with a temporary delivery-none smoke cron using payload.model = "litellm/gemini-3-flash".

Representative diagnostic, redacted/abridged:

cron payload.model 'litellm/gemini-3-flash' rejected by agents.defaults.models allowlist:
litellm/gemini-3-flash is not in [..., litellm/gemini-3-flash-preview, litellm/gemini-3.1-pro-preview, ...]

Likely code path from current openclaw/openclaw source (cd019cfa when checked):

  • src/plugin-sdk/provider-model-id-normalize.ts defines Google preview normalization, including gemini-3-flash -> gemini-3-flash-preview and gemini-3.1-pro -> gemini-3.1-pro-preview.
  • src/agents/model-ref-shared.ts is provider-scoped for this normalization in normalizeBuiltInProviderModelId(), applying it only for google, google-gemini-cli, and google-vertex.
  • But src/config/model-input.ts currently has normalizeAgentModelRefForConfig(model) split provider/model and then call normalizeGooglePreviewModelId() on the suffix regardless of provider:
const provider = normalizeProviderId(trimmed.slice(0, slash));
const normalizedModel = normalizeGooglePreviewModelId(trimmed.slice(slash + 1));
return modelKeyForConfig(provider, normalizedModel);

This can rewrite litellm/gemini-3-flash into litellm/gemini-3-flash-preview while preserving the non-Google provider prefix, which matches the observed runtime allowlist mismatch.

Cron then rejects the original payload model in src/cron/isolated-agent/model-selection.ts via resolveAllowedModelRef() / allowlist validation, producing the observed cron payload.model ... rejected by agents.defaults.models allowlist error.

Impact and severity

Affected: cron jobs that use payload.model with custom/non-Google LiteLLM-backed provider ids whose model ids happen to match Google Gemini preview-normalization aliases, e.g. litellm/gemini-3-flash.

Severity: High for affected installations because scheduled jobs fail before model dispatch.

Frequency: Always for the affected cron preflight path on 2026.5.18 in the observed setup.

Consequence: scheduled jobs silently accumulate cron preflight failures until the user changes the payload model, updates config, rolls back, or the normalization bug is fixed.

Additional information

Temporary workaround: migrate affected cron payloads away from litellm/gemini-3-flash to a non-affected configured model such as litellm/minimax-m2.5-aws or another model id that does not trigger Gemini preview normalization.

Interactive agent primary model paths may not fail the same way: in the observed setup, an interactive agent configured with litellm/gemini-3-flash was runtime-normalized and could still execute, but the effective model differed from source config. The hard failure was specifically reproduced in cron payload preflight.

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

A cron payload model should be accepted when it exactly matches a configured provider catalog entry and an agents.defaults.models allowlist entry for that same provider/model key.

In the observed setup, litellm/gemini-3-flash should remain litellm/gemini-3-flash because the configured provider is a custom LiteLLM-backed OpenAI-compatible provider. Google preview model-id normalization should not rewrite the model id unless the provider is Google/Google Gemini CLI/Google Vertex, or the configured provider explicitly opts into such normalization.

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 - 💡(How to fix) Fix [Bug]: cron preflight normalizes LiteLLM-backed Gemini model allowlist entries to Google preview IDs