openclaw - ✅(Solved) Fix web_search reports 'no provider available' from first-class assistant tools when capability + runtime succeed [2 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#77073Fetched 2026-05-05 05:52:42
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
2
Author
Timeline (top)
cross-referenced ×4closed ×1commented ×1

Fix Action

Fixed

PR fix notes

PR #77074: fix(web-search): keep first-class web_search runtime providers visible

Description (problem / solution / changelog)

Summary

Fixes #77073 — first-class assistant web_search reported web_search is disabled or no provider is available even when openclaw capability web search and direct runtime provider execution succeeded against the same configured Brave plugin.

Two source-only fixes:

  • src/agents/tools/web-search.ts — when lateBindRuntimeConfig: true:
    • runtimeWebSearch falls back to options?.runtimeWebSearch when getActiveRuntimeWebToolsMetadata()?.search is null (in agent contexts that do not share the gateway in-process runtime snapshot).
    • config falls back to options?.config when getActiveSecretsRuntimeSnapshot() is null.
    • Derives configuredProviderId from config.tools.web.search.provider and uses runtimeProviderId || configuredProviderId to decide preferRuntimeProviders, so an explicit Brave/Perplexity selection still routes through runtime provider discovery when the runtime metadata is unbound.
  • src/plugins/web-provider-runtime-shared.ts — when getLoadedRuntimePluginRegistry(...) returns a registry that maps to zero web providers, fall through to a scoped plugin load instead of treating that empty active registry as authoritative. Explicit onlyPluginIds: [] still short-circuits to [] to preserve the empty-scope contract for both resolvePluginWebProviders and resolveRuntimeWebProviders.

Why

The active gateway plugin registry is intentionally scoped to channels, memory, harnesses, and sidecars on startup. It can be otherwise compatible with the active OpenClaw config while contributing zero web-provider entries (e.g. when Brave/web providers live in a separately-loaded plugin set). Without a fall-through, the assistant's first-class web_search tool sees that empty active result as authoritative and reports "no provider available" — even though openclaw capability web search and the direct runtime path use a scoped load and find the configured provider just fine.

Late-binding compounded the problem: in agent contexts where the active-runtime/active-secrets globals are not set, the late-bound execute lambda lost both runtimeWebSearch and config, leaving preferRuntimeProviders unable to route to the configured plugin.

Test plan

  • node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/web-provider-runtime-shared.test.ts — 13 / 13 passed (4 new fall-through cases added).
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-tools.config.ts src/agents/tools/web-search.late-bind.test.ts — 6 / 6 passed (new file, covers both ?? fallbacks, configured-provider routing, no-selection guard, bundled manifest owner precedence, and active-runtime priority).
  • Re-ran adjacent web-search.test.ts and web-search.signal.test.ts to confirm no regression.
  • pnpm exec oxfmt --check --threads=1 on the four touched files — clean.

Notes

  • Diff is source-only. No dist bundle edits, no backup files, no shell patch scripts.
  • Pre-existing failures in 7 unrelated plugins/web-provider* test files were observed identically with and without this branch (manifest-registry mock and source-checkout-runtime fixture issues). They are not affected by this change.

🤖 Generated with Claude Code

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/tools/web-search.late-bind.test.ts (added, +165/-0)
  • src/agents/tools/web-search.ts (modified, +12/-3)
  • src/plugins/web-provider-runtime-shared.test.ts (modified, +114/-0)
  • src/plugins/web-provider-runtime-shared.ts (modified, +18/-4)

PR #77194: fix(plugins): allowlist bundled provider discovery

Description (problem / solution / changelog)

Summary

  • Makes bundled provider discovery honor restrictive plugins.allow by default for fresh/new configs; omitted bundled provider plugins no longer appear in setup/runtime/web-search inventory unless allowed.
  • Adds doctor legacy migration so existing non-empty plugins.allow configs with no explicit plugins.bundledDiscovery get stamped as "compat", preserving upgrade behavior until the operator opts into "allowlist".
  • Keeps compat behavior explicit across provider setup/runtime activation and public-artifact web provider fallback, while keeping empty allowlists open.
  • Updates generated config schema/docs/changelog and adds regression coverage for provider inventory, web-search fallback, and doctor migration/warning paths.

Verification

  • pnpm test src/plugins/providers.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/web-search-providers.runtime.test.ts src/plugins/web-provider-public-artifacts.fallback.test.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts src/commands/doctor/shared/legacy-config-migrate.test.ts src/commands/doctor-config-flow.test.ts src/config/schema.help.quality.test.ts src/config/schema.base.generated.test.ts
  • pnpm config:schema:check
  • pnpm config:docs:check
  • pnpm format:docs:check
  • pnpm exec oxfmt --check --threads=1 src/plugins/activation-context.ts src/plugins/bundled-compat.ts src/plugins/providers.ts src/plugins/providers.test.ts src/plugins/web-provider-public-artifacts.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/commands/doctor/shared/legacy-config-migrations.runtime.providers.ts src/commands/doctor/shared/legacy-config-migrate.test.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts src/config/types.plugins.ts src/config/schema.help.ts src/config/schema.base.generated.ts
  • git diff --check
  • pnpm build
  • Blacksmith Testbox tbx_01kqtfemz7e4jz8b829j4z4pt1: pnpm check:changed

Fixes #75575.

Additional verification after PR rewrite on 2026-05-04

  • pnpm test src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/providers.test.ts
  • pnpm config:schema:check
  • pnpm config:docs:check
  • pnpm exec oxfmt --check --threads=1 src/plugins/web-provider-public-artifacts.ts src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/bundled-compat.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts
  • git diff --check

Additional verification after alias follow-up on 2026-05-04

  • pnpm test src/agents/models-config.providers.plugin-allowlist-compat.test.ts
  • pnpm test src/plugins/web-provider-public-artifacts.fallback.test.ts src/plugins/web-search-providers.runtime.test.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts src/plugins/providers.test.ts
  • pnpm exec oxfmt --check --threads=1 src/plugins/bundled-compat.ts src/agents/models-config.providers.plugin-allowlist-compat.test.ts
  • git diff --check

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/.generated/config-baseline.sha256 (modified, +2/-2)
  • docs/gateway/configuration-reference.md (modified, +5/-0)
  • docs/gateway/doctor.md (modified, +3/-1)
  • docs/tools/plugin.md (modified, +16/-8)
  • src/agents/models-config.providers.plugin-allowlist-compat.test.ts (modified, +95/-1)
  • src/commands/doctor-config-flow.ts (modified, +8/-5)
  • src/commands/doctor/shared/legacy-config-migrate.test.ts (modified, +27/-0)
  • src/commands/doctor/shared/legacy-config-migrations.runtime.providers.ts (modified, +34/-0)
  • src/commands/doctor/shared/plugin-tool-allowlist-warnings.test.ts (modified, +34/-1)
  • src/commands/doctor/shared/plugin-tool-allowlist-warnings.ts (modified, +18/-0)
  • src/config/schema.base.generated.ts (modified, +12/-0)
  • src/config/schema.help.ts (modified, +2/-0)
  • src/config/schema.labels.ts (modified, +1/-0)
  • src/config/types.plugins.ts (modified, +10/-0)
  • src/config/zod-schema.ts (modified, +1/-0)
  • src/plugins/activation-context.ts (modified, +9/-1)
  • src/plugins/bundled-compat.ts (modified, +16/-1)
  • src/plugins/contracts/loader.contract.test.ts (modified, +2/-0)
  • src/plugins/providers.test.ts (modified, +105/-26)
  • src/plugins/providers.ts (modified, +13/-1)
  • src/plugins/web-provider-public-artifacts.fallback.test.ts (modified, +98/-0)
  • src/plugins/web-provider-public-artifacts.ts (modified, +27/-8)
  • src/plugins/web-search-providers.runtime.test.ts (modified, +58/-1)

Code Example

web_search is disabled or no provider is available
RAW_BUFFERClick to expand / collapse

Symptom

The first-class assistant web_search tool fails with:

web_search is disabled or no provider is available

…even though the same machine resolves the configured Brave plugin successfully via:

  • openclaw capability web search
  • Direct runtime provider execution (the gateway's web search runtime path)

Affected Surface

  • src/agents/tools/web-search.tscreateWebSearchTool with lateBindRuntimeConfig: true
  • src/plugins/web-provider-runtime-shared.tsresolvePluginWebProviders / resolveRuntimeWebProviders

The bug only reproduces when the assistant tool is built with lateBindRuntimeConfig: true from src/agents/openclaw-tools.ts and the agent context does not share the gateway's in-process runtime snapshot (e.g. embedded subagents, scoped runtime plugin loads).

Probable Cause

Two interacting regressions:

  1. The active gateway plugin registry is intentionally scoped to channels, memory, harnesses, and sidecars on startup. It can be otherwise compatible with the active OpenClaw config while contributing zero web-provider entries (e.g. when Brave/web providers live in a separately-loaded plugin set). The current resolver treats that empty active-registry result as authoritative and short-circuits to [] instead of falling back to a scoped provider plugin load. First-class tools then see no providers.

  2. When the late-bound createWebSearchTool execute lambda runs in an agent context where neither getActiveRuntimeWebToolsMetadata() nor getActiveSecretsRuntimeSnapshot() is populated, the local runtimeWebSearch and config both resolve to undefined. With no provider id and no config, preferRuntimeProviders cannot route to the configured plugin, and the tool ultimately reports "no provider available". The configured provider id from config.tools.web.search.provider is never consulted.

Proposed Fix Scope

Source-only fixes in src/agents/tools/web-search.ts and src/plugins/web-provider-runtime-shared.ts:

  • Late-bind config / runtime fallback in createWebSearchTool:
    • runtimeWebSearch = getActiveRuntimeWebToolsMetadata()?.search ?? options?.runtimeWebSearch
    • config = getActiveSecretsRuntimeSnapshot()?.config ?? options?.config
    • Derive configuredProviderId from config.tools.web.search.provider.
    • Compose providerSelectionId = runtimeProviderId || configuredProviderId and use that for preferRuntimeProviders, so an explicit Brave/Perplexity selection still resolves the configured plugin when no runtime provider id is bound.
  • Web provider runtime registry fallback:
    • When the compatible/runtime active plugin registry maps to zero web providers, fall through to a scoped provider plugin load instead of returning [].
    • Preserve explicit onlyPluginIds: [] semantics: an explicitly empty scope still returns [].

Targeted regression tests:

  • src/plugins/web-provider-runtime-shared.test.ts — fall-through under empty active registry, no fall-through under explicit empty scope, both for resolvePluginWebProviders and resolveRuntimeWebProviders.
  • src/agents/tools/web-search.late-bind.test.ts (new) — ?? fallbacks for runtime metadata and config; configured-provider-only routing; no preferRuntimeProviders when nothing is selected; bundled-manifest owner takes priority over runtime preference.

A PR implementing these fixes will follow.

extent analysis

TL;DR

The issue can be fixed by implementing a late-bind config/runtime fallback in createWebSearchTool and modifying the web provider runtime registry to fall back to a scoped provider plugin load when the active registry maps to zero web providers.

Guidance

  • Modify createWebSearchTool to derive configuredProviderId from config.tools.web.search.provider and compose providerSelectionId using runtimeProviderId and configuredProviderId.
  • Update the web provider runtime registry to fall through to a scoped provider plugin load when the compatible/runtime active plugin registry maps to zero web providers.
  • Preserve explicit onlyPluginIds: [] semantics to ensure an explicitly empty scope still returns [].
  • Implement targeted regression tests to verify the fixes, including tests for fall-through under empty active registry and no fall-through under explicit empty scope.

Example

// Modified createWebSearchTool function
const createWebSearchTool = (options) => {
  const runtimeWebSearch = getActiveRuntimeWebToolsMetadata()?.search ?? options?.runtimeWebSearch;
  const config = getActiveSecretsRuntimeSnapshot()?.config ?? options?.config;
  const configuredProviderId = config.tools.web.search.provider;
  const providerSelectionId = runtimeProviderId || configuredProviderId;
  // Use providerSelectionId for preferRuntimeProviders
};

Notes

The proposed fix scope is limited to source-only fixes in src/agents/tools/web-search.ts and src/plugins/web-provider-runtime-shared.ts. The fixes may not apply if the issue is caused by other factors not mentioned in the problem description.

Recommendation

Apply the proposed workaround by implementing the late-bind config/runtime fallback and modifying the web provider runtime registry. This should resolve the issue and allow the first-class assistant web_search tool to function correctly.

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