openclaw - ✅(Solved) Fix [Bug]: openclaw-schema.json nests $defs inside qqbot config instead of root level [4 pull requests, 1 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#60759Fetched 2026-04-08 02:47:30
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
cross-referenced ×3referenced ×1

When OpenClaw generates openclaw-schema.json, the \$defs block is incorrectly nested under properties.plugins.entries.properties.qqbot.properties.config.\$defs instead of being placed at the schema root level.

This causes all \$ref references pointing to these definitions (e.g. "\\$ref": "#/\\$defs/account") to fail resolution, breaking JSON Schema validation in editors like VS Code.

Error Message

  1. Observe validation error: \\$ref "/defs/account" in "file:///...openclaw-schema.json" can not be resolved

Root Cause

When OpenClaw generates openclaw-schema.json, the \$defs block is incorrectly nested under properties.plugins.entries.properties.qqbot.properties.config.\$defs instead of being placed at the schema root level.

This causes all \$ref references pointing to these definitions (e.g. "\\$ref": "#/\\$defs/account") to fail resolution, breaking JSON Schema validation in editors like VS Code.

Fix Action

Workaround

Move the \$defs block from the qqbot config to the schema root:

python3 -c "
import json
with open(openclaw-schema.json) as f:
    schema = json.load(f)
qqbot = schema[\"properties\"][\"plugins\"][\"properties\"][\"entries\"][\"properties\"][\"qqbot\"][\"properties\"][\"config\"]
schema[\"\\$defs\"] = qqbot.pop(\"\\$defs\")
with open(openclaw-schema.json, \"w\") as f:
    json.dump(schema, f, indent=2, ensure_ascii=False)
"

PR fix notes

PR #60770: fix(schema): hoist plugin/channel $defs to root level

Description (problem / solution / changelog)

Summary

Fixes #60759

When plugins or channels provide JSON schemas with $defs blocks (e.g., from Zod's toJSONSchema()), these definitions were being nested inside the plugin's config object instead of at the schema root level. This caused all $ref references to fail resolution since they point to #/$defs/<name> (root level).

Changes

  • Extract $defs from plugin/channel schemas during schema merging
  • Namespace definition names by plugin/channel ID to avoid conflicts (e.g., qqbot_account)
  • Rewrite all $ref pointers to use namespaced names
  • Hoist the namespaced definitions to the root schema's $defs

Example

A qqbot plugin with $defs.account now becomes $defs.qqbot_account at root level, and all $ref: "#/$defs/account" in the plugin schema become $ref: "#/$defs/qqbot_account".

Testing

Added 3 new tests:

  • Plugin schema $defs hoisting
  • Channel schema $defs hoisting
  • Nested $refs inside definitions are also rewritten

All existing tests continue to pass.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/config/schema.test.ts (modified, +276/-0)
  • src/config/schema.ts (modified, +143/-10)

PR #61695: feat(config): publish hosted schema artifact

Description (problem / solution / changelog)

Summary

  • Problem: #22278 is still open because OpenClaw can export the config schema locally, but it still does not publish a stable docs-hosted schema URL or default new configs to that URL.
  • Why it matters: editors and CI users still have to wire schema support manually, and publishing the current generated artifact as-is would ship the broken nested $defs layout reported in #60759.
  • What changed: route the editor-facing schema through a shared helper, publish a tracked docs/schema/openclaw.json artifact through the existing pnpm config:docs:gen/check flow, default newly created configs to https://docs.openclaw.ai/schema/openclaw.json, and hoist nested plugin/channel $defs to the schema root so the published artifact validates.
  • What did NOT change (scope boundary): this does not add the local startup-maintenance behavior proposed in #55390, and it does not backfill $schema into already-existing configs.

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 #22278
  • Closes #60759
  • Related #54523
  • Related #60067
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the repo had no tracked docs-hosted config schema artifact wired into the existing config-doc baseline flow, config writes preserved $schema when present but never supplied a default for newly created configs, and schema merging embedded plugin-owned root $defs inside nested config nodes while leaving $ref values pointing at document-root #/$defs/....
  • Missing detection / guardrail: there was no regression coverage asserting that merged plugin schemas hoist root $defs, and the docs baseline flow did not own a tracked schema artifact to validate/publish.
  • Contributing context (if known): #54523 and #60067 landed the local CLI export and richer schema docs first, so the remaining hosted-schema work stayed open in #22278.

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/config/schema.test.ts, src/config/io.write-config.test.ts, src/config/doc-baseline.integration.test.ts
  • Scenario the test should lock in: merged plugin schemas hoist nested $defs to the document root, newly created configs default $schema to the hosted docs URL, existing configs are not backfilled, and the config-doc baseline flow writes/checks the tracked schema artifact.
  • Why this is the smallest reliable guardrail: the behavior lives entirely in schema assembly, config write serialization, and the baseline artifact generator, so targeted unit/integration coverage exercises the exact affected seams without needing a full docs deploy.
  • Existing test that already covers this (if any): config schema export tests already cover the root $schema field shape; this PR adds the missing hosted-artifact and $defs regression coverage.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • docs/schema/openclaw.json becomes the tracked published config schema artifact for docs hosting.
  • New configs created through first-write flows default $schema to https://docs.openclaw.ai/schema/openclaw.json when the field is missing.
  • The published/generated schema now keeps plugin-owned $defs at the document root, so editors can resolve refs like #/$defs/account correctly.

Diagram (if applicable)

Before:
openclaw config schema -> local-only output
plugin config $defs -> nested under plugins.entries.<id>.config -> root $ref targets break
new config write -> no default $schema

After:
shared editor schema helper -> tracked docs/schema/openclaw.json -> docs host publishes stable URL
plugin config $defs -> hoisted to schema root -> root $ref targets resolve
new config write -> default hosted $schema URL

Security Impact (required)

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

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node.js local dev clone
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted): minimal gateway.mode=local temp config for first-write verification

Steps

  1. On current main before this patch, check the proposed hosted schema URL and observe it is missing.
  2. Generate the schema artifact locally and inspect the qqbot plugin branch to see config.$defs nested under plugins.entries.qqbot.properties.config while refs still target #/$defs/....
  3. Apply this patch and run pnpm config:docs:gen, pnpm config:docs:check, and the targeted config/schema tests listed above.
  4. Inspect docs/schema/openclaw.json and verify root $defs exists, nested qqbot.config.$defs is gone, and new first-write configs receive the hosted $schema URL.

Expected

  • Stable tracked docs schema artifact exists.
  • Generated schema keeps plugin-owned root defs at the document root.
  • New configs default $schema to the hosted docs URL.

Actual

  • Verified locally.

Evidence

Attach at least one:

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

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • pnpm config:docs:gen writes docs/schema/openclaw.json and updates the baseline hash.
    • pnpm config:docs:check passes with the tracked schema artifact in place.
    • Targeted Vitest checks pass for schema merge hoisting, first-write $schema defaulting, non-backfill behavior, and baseline artifact generation.
    • The generated schema now has root $defs and no longer nests qqbot.config.$defs.
  • Edge cases checked:
    • Existing configs without $schema are left unchanged on ordinary rewrites.
    • Duplicate hoisted $defs entries only merge when structurally identical; conflicting names throw instead of silently corrupting refs.
  • What you did not verify:
    • I did not verify the post-merge docs deployment itself.
    • pnpm build on latest origin/main is still blocked by the unrelated src/plugin-sdk/test-helpers.ts RmOptions type error.
    • The repo-wide pnpm check hook path is also blocked by unrelated latest-main tsgo failures outside this patch, so this PR is left draft until upstream red is understood.

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.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (Yes)
  • Migration needed? (No)
  • If yes, exact upgrade steps: new configs pick up $schema automatically; existing configs can add the hosted URL manually if desired.

Risks and Mitigations

  • Risk: publishing a schema artifact without fixing plugin $defs would ship an invalid editor schema.
    • Mitigation: hoist nested root $defs during schema merge and lock that in with a targeted regression test.
  • Risk: defaulting $schema on every write would create unwanted churn in existing configs.
    • Mitigation: only default the hosted URL on first-write/new-config flows; existing configs are not backfilled.

Attribution

  • Thanks @Kaspre for keeping the remaining hosted-schema scope precise on #22278 and for documenting the missing published artifact behavior.
  • Thanks @jojojonathan for the concrete $defs repro in #60759, which exposed the schema merge bug that had to be fixed before publishing the artifact.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/.generated/config-baseline.sha256 (modified, +1/-0)
  • docs/cli/config.md (modified, +3/-0)
  • docs/gateway/configuration.md (modified, +3/-0)
  • docs/schema/openclaw.json (added, +43476/-0)
  • scripts/generate-config-doc-baseline.ts (modified, +2/-1)
  • src/cli/config-cli.ts (modified, +2/-11)
  • src/config/doc-baseline.integration.test.ts (modified, +13/-0)
  • src/config/doc-baseline.ts (modified, +11/-1)
  • src/config/editor-schema.ts (added, +34/-0)
  • src/config/io.ts (modified, +4/-1)
  • src/config/io.write-config.test.ts (modified, +37/-0)
  • src/config/schema.test.ts (modified, +85/-0)
  • src/config/schema.ts (modified, +43/-2)
  • src/config/types.openclaw.ts (modified, +2/-0)

PR #1: fix: inline $defs/$ref in qqbot and webhooks plugin manifests [AI-assisted]

Description (problem / solution / changelog)

Summary

Fixes broken $ref resolution in openclaw config schema output. Fixes #60759.

Problem

The qqbot and webhooks openclaw.plugin.json manifests had hand-written configSchema blocks using JSON Schema $defs with $ref pointers (e.g. "$ref": "#/$defs/route") for DRY-ness. These are valid standalone, but openclaw config schema nests them inside the full config document tree. In draft-07, #/$defs/... resolves from the document root — after nesting, the pointer breaks.

Changes

Regenerate both configSchema blocks from the actual Zod source of truth (extensions/qqbot/src/config-schema.ts, extensions/webhooks/src/config.ts), which produces fully inlined JSON Schema with no $defs/$ref. This also corrects several schema inaccuracies vs the Zod runtime (e.g. allowFrom items now correctly include number, streaming.mode has required, clientSecret uses const per-variant with pattern constraints).

FileChange
extensions/qqbot/openclaw.plugin.jsonRegenerate configSchema from Zod — removes 7 $defs entries and 9 $ref pointers
extensions/webhooks/openclaw.plugin.jsonRegenerate configSchema from Zod — removes 3 $defs entries and 3 $ref pointers

Zero source code changes — data-only fix to two JSON manifest files.

Testing

pnpm check    # clean
pnpm build    # clean
pnpm test extensions/qqbot extensions/webhooks src/config/schema.test.ts  # all pass

AI Disclosure

  • Authored with Claude Opus 4.6 (Claude Code)
  • Schemas regenerated from Zod source, not hand-inlined
  • Fully tested (pnpm build && pnpm check && pnpm test)
  • I understand what the code does

Changed files

  • .github/labeler.yml (modified, +4/-0)
  • .github/workflows/ci.yml (modified, +119/-9)
  • .oxfmtrc.jsonc (modified, +2/-2)
  • .oxlintrc.json (modified, +4/-6)
  • AGENTS.md (modified, +4/-1)
  • CHANGELOG.md (modified, +136/-75)
  • CONTRIBUTING.md (modified, +5/-0)
  • INCIDENT_RESPONSE.md (added, +52/-0)
  • apps/ios/CHANGELOG.md (modified, +4/-0)
  • apps/ios/Config/Version.xcconfig (modified, +2/-2)
  • apps/ios/fastlane/metadata/en-US/release_notes.txt (modified, +1/-1)
  • apps/ios/version.json (modified, +1/-1)
  • apps/macos/Sources/OpenClaw/HostEnvSanitizer.swift (modified, +8/-1)
  • apps/macos/Sources/OpenClaw/HostEnvSecurityPolicy.generated.swift (modified, +273/-2)
  • apps/macos/Sources/OpenClawProtocol/GatewayModels.swift (modified, +103/-1)
  • apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift (modified, +103/-1)
  • docs/.generated/config-baseline.sha256 (modified, +4/-4)
  • docs/.generated/plugin-sdk-api-baseline.sha256 (modified, +2/-2)
  • docs/automation/cron-jobs.md (modified, +2/-0)
  • docs/automation/hooks.md (modified, +16/-0)
  • docs/ci.md (modified, +20/-19)
  • docs/cli/agents.md (modified, +1/-1)
  • docs/cli/approvals.md (modified, +50/-1)
  • docs/concepts/agent-loop.md (modified, +1/-1)
  • docs/concepts/model-providers.md (modified, +7/-0)
  • docs/concepts/qa-e2e-automation.md (modified, +60/-0)
  • docs/docs.json (modified, +3/-0)
  • docs/gateway/cli-backends.md (modified, +8/-0)
  • docs/gateway/configuration-reference.md (modified, +42/-5)
  • docs/gateway/configuration.md (modified, +1/-1)
  • docs/gateway/heartbeat.md (modified, +1/-0)
  • docs/gateway/protocol.md (modified, +13/-1)
  • docs/gateway/security/index.md (modified, +8/-6)
  • docs/gateway/troubleshooting.md (modified, +1/-1)
  • docs/help/testing.md (modified, +103/-1)
  • docs/help/troubleshooting.md (modified, +13/-11)
  • docs/plugins/codex-harness.md (added, +489/-0)
  • docs/plugins/manifest.md (modified, +25/-0)
  • docs/plugins/sdk-agent-harness.md (added, +264/-0)
  • docs/plugins/sdk-channel-plugins.md (modified, +1/-1)
  • docs/plugins/sdk-overview.md (modified, +16/-14)
  • docs/plugins/sdk-provider-plugins.md (modified, +7/-0)
  • docs/plugins/sdk-runtime.md (modified, +8/-2)
  • docs/reference/RELEASING.md (modified, +3/-3)
  • docs/reference/templates/AGENTS.md (modified, +0/-3)
  • docs/tools/browser.md (modified, +23/-2)
  • docs/tools/exec-approvals.md (modified, +26/-0)
  • docs/tools/reactions.md (modified, +1/-1)
  • docs/tools/skills.md (modified, +7/-0)
  • docs/tools/slash-commands.md (modified, +1/-0)
  • extensions/acpx/package.json (modified, +1/-1)
  • extensions/acpx/src/runtime-internals/mcp-command-line.test.ts (modified, +1/-1)
  • extensions/acpx/src/runtime.test.ts (modified, +10/-6)
  • extensions/active-memory/index.test.ts (modified, +20/-20)
  • extensions/active-memory/index.ts (modified, +8/-8)
  • extensions/amazon-bedrock/package.json (modified, +1/-1)
  • extensions/anthropic/cli-backend.ts (modified, +0/-2)
  • extensions/anthropic/cli-shared.test.ts (modified, +5/-3)
  • extensions/anthropic/cli-shared.ts (modified, +3/-4)
  • extensions/anthropic/stream-wrappers.test.ts (modified, +5/-5)
  • extensions/arcee/provider-catalog.ts (modified, +1/-3)
  • extensions/bluebubbles/src/conversation-bindings.test.ts (added, +60/-0)
  • extensions/bluebubbles/src/monitor-processing.ts (modified, +1/-1)
  • extensions/bluebubbles/src/monitor.test.ts (modified, +1/-1)
  • extensions/bluebubbles/src/setup-surface.ts (modified, +3/-3)
  • extensions/browser/browser-config.ts (modified, +4/-6)
  • extensions/browser/browser-control-auth.ts (modified, +5/-1)
  • extensions/browser/index.test.ts (modified, +1/-1)
  • extensions/browser/src/browser-tool.ts (modified, +1/-1)
  • extensions/browser/src/browser/act-policy.ts (added, +44/-0)
  • extensions/browser/src/browser/bridge-server.auth.test.ts (modified, +10/-1)
  • extensions/browser/src/browser/bridge-server.ts (modified, +12/-7)
  • extensions/browser/src/browser/cdp.helpers.test.ts (added, +65/-0)
  • extensions/browser/src/browser/cdp.helpers.ts (modified, +59/-14)
  • extensions/browser/src/browser/cdp.test.ts (modified, +54/-7)
  • extensions/browser/src/browser/cdp.ts (modified, +12/-15)
  • extensions/browser/src/browser/chrome-mcp.snapshot.ts (modified, +1/-1)
  • extensions/browser/src/browser/chrome-mcp.ts (modified, +3/-3)
  • extensions/browser/src/browser/chrome.executables.test.ts (added, +42/-0)
  • extensions/browser/src/browser/chrome.executables.ts (modified, +1/-1)
  • extensions/browser/src/browser/chrome.test.ts (modified, +2/-2)
  • extensions/browser/src/browser/chrome.ts (modified, +14/-6)
  • extensions/browser/src/browser/client-actions-core.ts (modified, +2/-87)
  • extensions/browser/src/browser/client-actions.types.ts (added, +87/-0)
  • extensions/browser/src/browser/client-fetch.loopback-auth.test.ts (modified, +46/-0)
  • extensions/browser/src/browser/client-fetch.ts (modified, +14/-12)
  • extensions/browser/src/browser/client.ts (modified, +2/-19)
  • extensions/browser/src/browser/client.types.ts (added, +19/-0)
  • extensions/browser/src/browser/config.test.ts (modified, +15/-4)
  • extensions/browser/src/browser/config.ts (modified, +13/-7)
  • extensions/browser/src/browser/control-auth.auto-token.test.ts (modified, +13/-5)
  • extensions/browser/src/browser/errors.test.ts (modified, +26/-1)
  • extensions/browser/src/browser/errors.ts (modified, +21/-1)
  • extensions/browser/src/browser/form-fields.ts (modified, +1/-1)
  • extensions/browser/src/browser/local-dispatch.runtime.ts (added, +20/-0)
  • extensions/browser/src/browser/navigation-guard.test.ts (modified, +88/-0)
  • extensions/browser/src/browser/navigation-guard.ts (modified, +40/-1)
  • extensions/browser/src/browser/profiles-service.test.ts (modified, +3/-1)
  • extensions/browser/src/browser/profiles-service.ts (modified, +5/-5)
  • extensions/browser/src/browser/pw-ai.ts (modified, +1/-0)

PR #64002: fix(qqbot,webhooks): inline $defs/$ref in plugin manifests [AI-assisted]

Description (problem / solution / changelog)

Summary

Fixes broken $ref resolution in openclaw config schema output when the emitted schema is saved to a file and referenced via "$schema" in openclaw.json. Fixes #60759.

Problem

The qqbot and webhooks openclaw.plugin.json manifests had hand-written configSchema blocks using JSON Schema $defs with $ref pointers (e.g. "$ref": "#/$defs/route") for DRY-ness. These resolve correctly standalone, but openclaw config schema nests them inside the full config document tree at paths like plugins.entries.qqbot.config and plugins.entries.webhooks.config. In draft-07, #/$defs/... resolves from the document root — after nesting, the pointer breaks and editors report:

$ref '/$defs/route' in 'file:///.../openclaw.schema.json' can not be resolved.

Changes

Inline each $ref target at its use site and remove the $defs block in both manifests. The resulting schemas are semantically identical to before — verified by deep $ref resolution + sorted-key JSON comparison against main.

FileChange
extensions/qqbot/openclaw.plugin.jsonInline 7 definitions (audioFormatPolicy, speechQueryParams, tts, stt, secretRef, secretInput, account); remove all 9 $ref pointers
extensions/webhooks/openclaw.plugin.jsonInline 3 definitions (secretRef, secretInput, route); remove all 3 $ref pointers

Zero source code changes — data-only fix to two JSON manifest files. 108 insertions, 150 deletions.

Testing

pnpm check    # clean (lint + typecheck + format)
pnpm build    # clean
pnpm test extensions/qqbot extensions/webhooks src/config/schema.test.ts  # all pass (129/129)

Verified by running openclaw config schema and confirming zero $defs and zero $ref in the 800 KB output, and that all qqbot/webhooks plugin entry fields are present in the emitted schema.

AI Disclosure

  • Authored with Claude Opus 4.6 (Claude Code)
  • Inlining done programmatically — semantically identical to main, verified via deep schema comparison
  • Fully tested (pnpm build && pnpm check && pnpm test)
  • I understand what the code does

Changed files

  • extensions/qqbot/openclaw.plugin.json (modified, +83/-118)
  • extensions/webhooks/openclaw.plugin.json (modified, +25/-32)

Code Example

"properties": {
  "plugins": {
    "properties": {
      "entries": {
        "properties": {
          "qqbot": {
            "properties": {
              "config": {
                "\$defs": {   // <-- WRONG: should be at root level
                  "audioFormatPolicy": {...},
                  "speechQueryParams": {...},
                  "tts": {...},
                  "stt": {...},
                  "secretRef": {...},
                  "secretInput": {...},
                  "account": {...}
                }
              }
            }
          }
        }
      }
    }
  }
}

---

"\\$ref": "#/\\$defs/account"  // line ~31262

---

python3 -c "
import json
with open(openclaw-schema.json) as f:
    schema = json.load(f)
qqbot = schema[\"properties\"][\"plugins\"][\"properties\"][\"entries\"][\"properties\"][\"qqbot\"][\"properties\"][\"config\"]
schema[\"\\$defs\"] = qqbot.pop(\"\\$defs\")
with open(openclaw-schema.json, \"w\") as f:
    json.dump(schema, f, indent=2, ensure_ascii=False)
"
RAW_BUFFERClick to expand / collapse

Description

When OpenClaw generates openclaw-schema.json, the \$defs block is incorrectly nested under properties.plugins.entries.properties.qqbot.properties.config.\$defs instead of being placed at the schema root level.

This causes all \$ref references pointing to these definitions (e.g. "\\$ref": "#/\\$defs/account") to fail resolution, breaking JSON Schema validation in editors like VS Code.

Reproduction

  1. Run openclaw config schema or let OpenClaw regenerate the schema
  2. Open ~/.openclaw/openclaw-schema.json in VS Code
  3. Observe validation error: \\$ref "/defs/account" in "file:///...openclaw-schema.json" can not be resolved

Evidence

The schema has \$defs at an incorrect nested path:

"properties": {
  "plugins": {
    "properties": {
      "entries": {
        "properties": {
          "qqbot": {
            "properties": {
              "config": {
                "\$defs": {   // <-- WRONG: should be at root level
                  "audioFormatPolicy": {...},
                  "speechQueryParams": {...},
                  "tts": {...},
                  "stt": {...},
                  "secretRef": {...},
                  "secretInput": {...},
                  "account": {...}
                }
              }
            }
          }
        }
      }
    }
  }
}

But references in the schema point to root level:

"\\$ref": "#/\\$defs/account"  // line ~31262

Workaround

Move the \$defs block from the qqbot config to the schema root:

python3 -c "
import json
with open(openclaw-schema.json) as f:
    schema = json.load(f)
qqbot = schema[\"properties\"][\"plugins\"][\"properties\"][\"entries\"][\"properties\"][\"qqbot\"][\"properties\"][\"config\"]
schema[\"\\$defs\"] = qqbot.pop(\"\\$defs\")
with open(openclaw-schema.json, \"w\") as f:
    json.dump(schema, f, indent=2, ensure_ascii=False)
"

Environment

  • OpenClaw: v2026.4.2 (d74a122)
  • First observed: v2026.3.31
  • Recurred after: schema regeneration in v2026.4.1+
  • OS: Ubuntu 24.04 on WSL2

Related

  • #22278 (Feature: Publish schema to docs + auto-regenerate on release)

extent analysis

TL;DR

Move the $defs block from the qqbot config to the schema root level to fix JSON Schema validation issues.

Guidance

  • Verify the issue by checking the openclaw-schema.json file for the incorrect nesting of the $defs block under properties.plugins.entries.properties.qqbot.properties.config.$defs.
  • Use the provided Python script as a workaround to move the $defs block to the schema root level.
  • Check the schema references (e.g., "$ref": "#/$defs/account") to ensure they point to the correct location after moving the $defs block.
  • Consider reporting this issue to the OpenClaw developers to ensure a permanent fix is implemented, especially since it has recurred after schema regeneration in multiple versions.

Example

The provided Python script can be used as an example of how to move the $defs block:

import json
with open('openclaw-schema.json') as f:
    schema = json.load(f)
qqbot = schema["properties"]["plugins"]["properties"]["entries"]["properties"]["qqbot"]["properties"]["config"]
schema["$defs"] = qqbot.pop("$defs")
with open('openclaw-schema.json', "w") as f:
    json.dump(schema, f, indent=2, ensure_ascii=False)

Notes

This workaround assumes that the $defs block only contains definitions that are meant to be at the schema root level. If there are other definitions that are specific to the qqbot config, they may need to be handled separately.

Recommendation

Apply the workaround using the provided Python script to move the $defs block to the schema root level, as this will fix the immediate issue with JSON Schema validation.

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