Skip to content

bug(web-search): Settings test rejects env-provided API keys that runtime accepts #254

Description

@MicroMilo

UI-related note: this touches the Settings/UI path and may be lower priority during the ongoing frontend refactor.

Summary

The web search runtime can read provider API keys from environment variables, but the Settings Test button and /api/config/test-web-search require an inline key in the request body.

Why it matters

Production deployments commonly keep secrets in environment variables or custom env instead of writing them into config files. The actual agent runtime can use TAVILY_API_KEY, CUSTOM_WEB_SEARCH_API_KEY, GLM_WEB_SEARCH_API_KEY, or ZAI_API_KEY, but Settings cannot test that valid runtime configuration. This can push users toward copying secrets back into the UI/config just to make the test button work.

Evidence

  • src/tool/builtin/webSearch.ts:140 resolves the runtime key through resolveApiKey(...).
  • src/tool/builtin/webSearch.ts:142 only fails when no key is available and the provider is not custom with auth: none.
  • src/tool/builtin/webSearch.ts:203 to src/tool/builtin/webSearch.ts:215 defines resolveApiKey(...) and reads TAVILY_API_KEY, CUSTOM_WEB_SEARCH_API_KEY, GLM_WEB_SEARCH_API_KEY, and ZAI_API_KEY from runtime context/env.
  • src/tool/builtin/webSearch.ts:497 to src/tool/builtin/webSearch.ts:507 injects the resolved key into bearer, query, or body auth modes.
  • ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:2002 to ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:2008 computes trimmedKey only from the inline apiKey field and returns before testing when it is empty.
  • ui/src/components/settings/view/tabs/PilotDeckConfigTab.tsx:2170 disables the Test button when !hasUsableSecret(apiKey).
  • ui/server/routes/config.js:322 to ui/server/routes/config.js:324 computes trimmedKey from req.body.apiKey and returns API key is required. unless the provider is custom with auth: none.

Validation

Validation level: dynamic runtime reproduction plus UI/server source control-flow confirmation.

Reproduction used a mocked custom bearer web-search provider with no inline key and env.CUSTOM_WEB_SEARCH_API_KEY = "env-secret".

Key output: the runtime request included Authorization: Bearer env-secret, proving the actual tool path accepts env-provided keys. In contrast, the Settings route checks only body/input apiKey and returns API key is required. before reaching equivalent runtime key resolution.

Boundary: this did not launch the full browser UI. The disabled-button behavior and early return are confirmed from the Settings component source, and the server rejection is confirmed from the route source.

Expected behavior

Settings Test should be able to validate the same web search configuration that the runtime can execute. If a provider key is available from env/customEnv, the UI/server test path should allow testing without requiring the secret to be pasted inline.

Existing coverage checked

No existing issue or PR was found that fixes env-key support for the Settings Test path. PR #182 handles friendlier behavior for unconfigured web search, but it does not make /api/config/test-web-search use runtime-equivalent key resolution. Issue #68 is related background for custom env propagation, but it does not cover this Settings Test/runtime mismatch.

Coverage checked by searching for TAVILY_API_KEY test-web-search, CUSTOM_WEB_SEARCH_API_KEY, hasUsableSecret webSearch, and API key is required.

Suggested fix

Make the backend test route use the same key-resolution semantics as the runtime. The frontend should allow testing when an env/customEnv key is available and make the key source clear to the user.

The route should still reject missing credentials when neither inline config nor env/customEnv provides a key, except for custom with auth: none.

Suggested tests

  • Tavily test succeeds with TAVILY_API_KEY and no inline key.
  • Custom bearer test succeeds with CUSTOM_WEB_SEARCH_API_KEY and no inline key.
  • GLM/ZAI test succeeds with GLM_WEB_SEARCH_API_KEY or ZAI_API_KEY and no inline key.
  • Missing inline key and missing env key still fails with a clear error.
  • custom with auth: none continues to allow an empty key.

Submitted with Codex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions