openclaw - 💡(How to fix) Fix Bug: agents.defaults.models record-format allowlist stripped at gateway startup despite passing Zod validation (4.23/4.24) [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#73218Fetched 2026-04-29 06:22:07
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
closed ×1commented ×1

Setting agents.defaults.models as a record (map keyed by provider/model, values are empty objects) per the documented schema results in the field being silently removed from the runtime config when the gateway starts. Reproducible 100% on OpenClaw 2026.4.23 and 2026.4.24.

Root Cause

Setting agents.defaults.models as a record (map keyed by provider/model, values are empty objects) per the documented schema results in the field being silently removed from the runtime config when the gateway starts. Reproducible 100% on OpenClaw 2026.4.23 and 2026.4.24.

Fix Action

Fix / Workaround

Workaround / current state

Code Example

{
     "agents": {
       "defaults": {
         "model": { "primary": "dos-ai/dos-ai" },
         "models": {
           "dos-ai/dos-ai": {},
           "dos-ai/dos-auto": {}
         }
       }
     }
   }
RAW_BUFFERClick to expand / collapse

Summary

Setting agents.defaults.models as a record (map keyed by provider/model, values are empty objects) per the documented schema results in the field being silently removed from the runtime config when the gateway starts. Reproducible 100% on OpenClaw 2026.4.23 and 2026.4.24.

Reproduction

  1. Write /root/.openclaw/openclaw.json containing:

    {
      "agents": {
        "defaults": {
          "model": { "primary": "dos-ai/dos-ai" },
          "models": {
            "dos-ai/dos-ai": {},
            "dos-ai/dos-auto": {}
          }
        }
      }
    }

    (plus the rest of a valid config; dos-ai provider is loaded with a matching catalog.)

  2. Confirm openclaw doctor accepts the record-format value:

    • Exit code 0
    • No Invalid input: expected record warning (the warning DOES fire if you instead pass an array - confirms the schema expects a record)
    • File hash unchanged after doctor run
  3. Confirm openclaw config set agents.defaults.models '{...}' --strict-json --merge accepts and persists the field. CLI prints Updated agents.defaults.models. Restart the gateway to apply.

  4. Restart the gateway: openclaw gateway run --bind lan (or docker restart for our setup)

  5. After restart, observe that /root/.openclaw/openclaw.json no longer contains agents.defaults.models. The field is silently dropped. openclaw config get agents.defaults.models returns empty.

  6. Multiple openclaw.json.clobbered.<timestamp> backups appear next to the active config, each one missing the field too.

Expected behavior

agents.defaults.models is documented as the model picker allowlist (docs/concepts/model-providers.md, docs/cli/configure.md, docs/cli/config.md). The Zod schema in src/config/zod-schema.agent-defaults.ts defines it as z.record(z.string(), z.object({alias?, params?, streaming?}).strict()).optional(). An empty inner object should be valid and persist.

Actual behavior

Gateway startup writes the file back without the field. Schema validation alone is fine; some later normalization step silently drops it. We have not identified which code path performs the strip.

Impact

The Control UI /model picker enumerates ~900 plugin-known model ids that we do not proxy. With models.mode: "replace" set, invocations of unsupported models still get a clean 400 from the gateway, so this is not a correctness or CPU-loop issue - but the picker is unusable.

Workaround / current state

models.mode: "replace" plus plugins.deny of all non-dos-ai providers prevents runtime invocation of unsupported models. The picker remains visually noisy.

Environment

  • OpenClaw 2026.4.23 and 2026.4.24
  • Linux Docker container, Alpine base
  • Self-hosted on multi-tenant agent platform (DOS.AI)

Happy to add more detail or PR the schema docs if useful.

extent analysis

TL;DR

The agents.defaults.models field is being silently removed from the runtime config when the gateway starts, likely due to a normalization step that drops empty objects.

Guidance

  • Verify that the agents.defaults.models field is correctly formatted as a record with non-empty objects, as the Zod schema defines it as z.record(z.string(), z.object({alias?, params?, streaming?}).strict()).optional().
  • Check the gateway startup code for any normalization steps that might be dropping the agents.defaults.models field, potentially due to it being an empty object.
  • Consider adding a minimal set of required properties to the agents.defaults.models objects to prevent them from being considered empty.
  • Review the openclaw.json file and its backups to ensure that the field is being written correctly before the gateway startup.

Example

No code snippet is provided as the issue seems to be related to the configuration and normalization of the agents.defaults.models field.

Notes

The issue might be specific to the OpenClaw versions 2026.4.23 and 2026.4.24, and further investigation is needed to determine the root cause.

Recommendation

Apply a workaround by ensuring that the agents.defaults.models objects have at least one property, such as alias or params, to prevent them from being considered empty and dropped during normalization.

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

agents.defaults.models is documented as the model picker allowlist (docs/concepts/model-providers.md, docs/cli/configure.md, docs/cli/config.md). The Zod schema in src/config/zod-schema.agent-defaults.ts defines it as z.record(z.string(), z.object({alias?, params?, streaming?}).strict()).optional(). An empty inner object should be valid and persist.

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: agents.defaults.models record-format allowlist stripped at gateway startup despite passing Zod validation (4.23/4.24) [1 comments, 2 participants]