openclaw - 💡(How to fix) Fix [Bug]: Gateway startup fails — mergeScopedSearchConfig injects shape that validator rejects (tools.web.search.<plugin> legacy) [3 pull requests]

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…

Error Message

  1. Observe error above. openclaw config validate (CLI) reports "Config valid" — only the runtime validator fails. The error reproduces with all of the following config shapes:
  • #63812 (closed) — same error string from the WebUI-save path. Closed but the symmetric startup-path variant (this issue) is still live.

Root Cause

Two code paths interact:

  1. mergeScopedSearchConfig in dist/web-search-provider-config-CM5VNRaS.js (function name same in source as in bundled output) — iterates installed plugins whose manifest declares compatibilityRuntimePaths: ["tools.web.search.<provider>" | "tools.web.search.apiKey"] and injects tools.web.search[pluginId] = pluginConfig.webSearch at gateway boot, before validation. This is the legacy-compat shim documented in plugin manifests like extensions/perplexity/openclaw.plugin.json.

  2. LEGACY_WEB_SEARCH_PROVIDER_CONFIG_KEYS validator in dist/zod-schema.agent-runtime-Bq5CXVVg.js — a superRefine callback that walks tools.web.search keys; if any key matches the legacy set {brave, duckduckgo, exa, firecrawl, gemini, grok, kimi, minimax, ollama, perplexity, searxng, tavily} AND its value is a plain object, it emits the "legacy web_search provider config must use plugins.entries.<plugin>.config.webSearch" issue.

The merge runs BEFORE the validator. So #1 injects exactly the shape #2 rejects. The two changes appear to have shipped without awareness of each other.

openclaw doctor --fix (and OPENCLAW_BETA=true openclaw doctor --fix) does NOT touch this case — it migrates messages.tts, auth-profiles.json, container registry shape, etc., but not the tools.web.search.<plugin> auto-injection. This was tested with both shapes above.

Fix Action

Fixed

Code Example

Gateway failed to start: Invalid config at /data/.openclaw/openclaw.json.
tools.web.search.perplexity: legacy web_search provider config must use plugins.entries.<plugin>.config.webSearch
Run "openclaw doctor --fix" to repair, then retry.

---

{
     "tools": { "web": { "search": { "enabled": true, "provider": "gemini" } } },
     "plugins": { "entries": { "perplexity": { "enabled": false } } }
   }
RAW_BUFFERClick to expand / collapse

TL;DR

OpenClaw gateway v2026.5.22 fails to start when tools.web.search exists in openclaw.json AND any legacy provider plugin (perplexity, gemini, duckduckgo, etc.) is installed — even if the plugin is disabled, even after openclaw doctor --fix (with OPENCLAW_BETA=true), and even with a freshly stripped config containing only the canonical shape.

Gateway failed to start: Invalid config at /data/.openclaw/openclaw.json.
tools.web.search.perplexity: legacy web_search provider config must use plugins.entries.<plugin>.config.webSearch
Run "openclaw doctor --fix" to repair, then retry.

This blocks fresh-container deploys / VM migrations. Existing long-running gateways with the same binary version on the same config bytes are unaffected — suggesting in-place upgrades from <2026.5.22 happen to dodge the check, but cold starts hit it deterministically.

Repro

  1. Install [email protected] (npm global). Verify openclaw --version2026.5.22 (a374c3a).
  2. openclaw plugins enable perplexity (or just have extensions/perplexity/openclaw.plugin.json resolvable — the install state alone is sufficient).
  3. In ~/.openclaw/openclaw.json:
    {
      "tools": { "web": { "search": { "enabled": true, "provider": "gemini" } } },
      "plugins": { "entries": { "perplexity": { "enabled": false } } }
    }
  4. Start gateway: openclaw or openclaw gateway start.
  5. Observe error above. openclaw config validate (CLI) reports "Config valid" — only the runtime validator fails.

The error reproduces with all of the following config shapes:

  • tools.web.search.<provider> = {…} (the literal rejected shape — legacy)
  • tools.web.search = { provider: "perplexity" } (the canonical shape)
  • tools.web.search = { enabled: true, provider: "gemini" } (a different provider, with perplexity plugin disabled)
  • Removing tools.web.search entirely from the JSON (the field re-appears at runtime, then is rejected)

Root cause analysis

Two code paths interact:

  1. mergeScopedSearchConfig in dist/web-search-provider-config-CM5VNRaS.js (function name same in source as in bundled output) — iterates installed plugins whose manifest declares compatibilityRuntimePaths: ["tools.web.search.<provider>" | "tools.web.search.apiKey"] and injects tools.web.search[pluginId] = pluginConfig.webSearch at gateway boot, before validation. This is the legacy-compat shim documented in plugin manifests like extensions/perplexity/openclaw.plugin.json.

  2. LEGACY_WEB_SEARCH_PROVIDER_CONFIG_KEYS validator in dist/zod-schema.agent-runtime-Bq5CXVVg.js — a superRefine callback that walks tools.web.search keys; if any key matches the legacy set {brave, duckduckgo, exa, firecrawl, gemini, grok, kimi, minimax, ollama, perplexity, searxng, tavily} AND its value is a plain object, it emits the "legacy web_search provider config must use plugins.entries.<plugin>.config.webSearch" issue.

The merge runs BEFORE the validator. So #1 injects exactly the shape #2 rejects. The two changes appear to have shipped without awareness of each other.

openclaw doctor --fix (and OPENCLAW_BETA=true openclaw doctor --fix) does NOT touch this case — it migrates messages.tts, auth-profiles.json, container registry shape, etc., but not the tools.web.search.<plugin> auto-injection. This was tested with both shapes above.

Why long-running gateways aren't affected

We have two boxes on identical [email protected] (a374c3a):

  • BLUE (production, GCE): in-place npm i -g [email protected] over an older release; the gateway process from the older binary keeps running and serves traffic fine. The on-disk validator is the new strict one, but the running process never re-reads it.
  • GREEN (fresh container, Hetzner): same binary version installed clean; fresh process; deterministic crash on first start.

This means the bug is masked from anyone who upgrades in-place without restarting, and only bites on fresh deploys (containers, new hosts, CI smoke).

What we tried

AttemptResult
openclaw doctor --fixMigrates other fields, does not touch this one
OPENCLAW_BETA=true openclaw doctor --fixSame — same migrations as without BETA
Strip tools.web.search entirely from openclaw.jsonField re-appears at runtime via mergeScopedSearchConfig, then rejected
Set canonical tools.web.search = { provider: "perplexity" } + enable perplexity pluginRejected same way
Set provider: "gemini", disable perplexity pluginStill rejected (gemini plugin also has compatibilityRuntimePaths)
Exact-bytes copy of working BLUE config to GREENRejected (confirms it's not config drift)
Restart BLUE process?Not yet — we held off in case it crashes prod

Suggested fix (one of)

A. Cleanest: change mergeScopedSearchConfig to inject into plugins.entries.<plugin>.config.webSearch instead of tools.web.search.<plugin>. The legacy shape is no longer auto-created, and the validator's rejection condition is no longer reachable from the merge path.

B. Cheaper: make the validator skip the legacy-shape check for keys that match an installed plugin's compatibilityRuntimePaths — i.e. trust the merge layer's output as already in transition. This preserves the strict check for hand-written legacy configs.

C. doctor --fix extension: have the doctor strip tools.web.search.<plugin> keys when the corresponding plugin is installed, mirror them into plugins.entries.<plugin>.config.webSearch if not already there, and write back. Lower-leverage than A/B but at least gives operators an escape hatch.

Environment

  • OpenClaw: 2026.5.22 (a374c3a)
  • Node: v22.19.0
  • OS: Debian 12 (Linux x64)
  • Install: npm i -g [email protected] inside Docker (node:22-bookworm-slim)
  • Config: /data/.openclaw/openclaw.json (mounted volume, 12GB carried over from BLUE)
  • Plugins installed: perplexity, gemini, kimi (others can repro too)

Related

  • #63812 (closed) — same error string from the WebUI-save path. Closed but the symmetric startup-path variant (this issue) is still live.
  • #80536 (open) — broader pattern of runtime validator drift from bundled schema metadata. Different mechanism but same "validator out of sync with merge/codegen" family.

Happy to PR fix B if that's the preferred direction — it's the least invasive and we can verify it on our fresh container immediately.

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 - 💡(How to fix) Fix [Bug]: Gateway startup fails — mergeScopedSearchConfig injects shape that validator rejects (tools.web.search.<plugin> legacy) [3 pull requests]