Skip to content

[Bug]: web_search fails in sub-agent sessions with bundled providers (Brave) after 2026.4.29 → 2026.5.2 #76416

Description

@marktran

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

After upgrading from 2026.4.29 to 2026.5.2, the web_search tool fails in sub-agent sessions with web_search is disabled or no provider is available, even though the bundled Brave plugin loads, the tool appears in the sub-agent's tool list, and the same call from a main-agent session succeeds.

Steps to reproduce

  1. Run OpenClaw 2026.5.2 with the bundled Brave plugin enabled and tools.web.search.provider = "brave". Configure plugins.entries.brave.config.webSearch.apiKey (any source — SecretRef via 1Password CLI, plain string, or env-var fallback). Verify web_search works in a main-agent session.
  2. From the main agent, spawn a sub-agent (e.g. via the subagents runner) whose tool allowlist narrows the active plugin registry — so the sub-agent's loaded registry does not include the brave plugin.
  3. Have the sub-agent call web_search.
  4. The call returns the error below; the equivalent main-agent call still succeeds.

Expected behavior

web_search resolves the bundled Brave provider in sub-agent sessions, as it did on 2026.4.29 — the bundled-provider lookup is config-driven, not session-registry-scoped.

Actual behavior

Sub-agent receives:

{ "status": "error", "tool": "web_search", "error": "web_search is disabled or no provider is available." }

A direct curl to https://api.search.brave.com/res/v1/web/search with the same credential succeeds, confirming the credential and network path are healthy.

OpenClaw version

2026.5.2

Operating system

Ubuntu 24.04.4 LTS (Linux 6.12.67 x86_64)

Install method

npm global (Node v24.14.1, mise-managed)

Model

anthropic/claude-sonnet-4-6 (sub-agent); main agent on anthropic/claude-opus-4-6

Provider / routing chain

openclaw -> brave-plugin -> api.search.brave.com

Additional provider/model setup details

The Brave plugin manifest declares contracts.webSearchProviders: ["brave"] but no contracts.tools. In a sub-agent session, resolvePluginToolRuntimePluginIds derives onlyPluginIds from the tool allowlist intersected with each plugin's contracts.tools — so brave is excluded from the sub-agent's onlyPluginIds and not loaded into its active registry.

Logs, screenshots, and evidence

Sub-agent trajectory excerpt (2026.5.2, claude-sonnet-4-6, sessionKey agent:main:subagent:<uuid>):

assistant -> toolCall: { "name": "web_search", "arguments": { "query": "..." } }
toolResult: {
  "status": "error",
  "tool": "web_search",
  "error": "web_search is disabled or no provider is available."
}

Impact and severity

  • Affected: any sub-agent task using native web_search against a bundled provider (Brave, Perplexity, etc.). The same code path is shared.
  • Severity: blocks workflow — sub-agents must fall back to exec + curl to reach the search API directly.
  • Frequency: 100% of sub-agent web_search attempts observed across multiple runs on 2026-05-02 / 2026-05-03.
  • Consequence: native web_search is unavailable inside sub-agents on 2026.5.2.

Root cause (from a source dive)

Between v2026.4.29 and v2026.5.2, createWebSearchTool in src/agents/tools/web-search.ts was rewritten to always use lateBindRuntimeConfig: true (src/agents/openclaw-tools.ts:424). In that path, line 95 sets config = undefined and the same undefined is passed to resolveManifestContractOwnerPluginId on line 102:

const config = options?.lateBindRuntimeConfig === true ? undefined : options?.config;
const preferRuntimeProviders =
  Boolean(runtimeProviderId) &&
  !resolveManifestContractOwnerPluginId({
    contract: "webSearchProviders",
    value: runtimeProviderId,
    origin: "bundled",
    config,            // <-- undefined when late-binding
  });

resolveManifestContractOwnerPluginId needs config context to discover the bundled-plugin manifest on disk. Without it, the lookup returns undefined for brave, so preferRuntimeProviders flips from false (the correct value for a bundled provider) to true. runWebSearch then routes through resolveRuntimeWebSearchProviders, which only consults the active runtime plugin registry — narrowed to the sub-agent's tool allowlist, which excludes brave (no contracts.tools). mapRegistryProviders returns [], candidates is empty, and runtime.ts:339 throws "web_search is disabled or no provider is available.".

In a main-agent session, the active registry still contains the bundled providers, so even with preferRuntimeProviders = true the candidate list is non-empty and the call succeeds.

Additional information

  • First known bad: 2026.5.2 (also reproduced against current origin/main).
  • Last known good: 2026.4.29.
  • Workaround for users: sub-agents call exec + curl against https://api.search.brave.com/res/v1/web/search with the same credential. Removing plugins.entries.brave.config.webSearch.apiKey and exporting BRAVE_API_KEY does not fix the sub-agent path — the runtime-registry lookup still misses brave regardless of credential source.
  • Patch in flight: PR will be opened with a regression test in src/agents/tools/web-tools.enabled-defaults.test.ts (fails on origin/main, passes after the fix) and a 6-line change in src/agents/tools/web-search.ts that late-binds the bundled-owner-lookup config to the active runtime snapshot.
  • Distinct from [Bug]: Brave plugin enabled in config but not loaded at runtime — web_search tool unavailable #68249 (plugin not loading at all on 2026.4.15) and [Bug]: 5.2 brave plugin install fails — missing openclaw.extensions, no @beta available #76373 (2026.5.2 install failure).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions