{"record":{"id":"c5c7183993e65b3e","repo":"can1357/oh-my-pi","slug":"provider-label-web-search-is-unavailable-confi","errorCode":null,"errorMessage":"${provider.label} web search is unavailable. Configure its credentials or select the automatic provider chain.","messagePattern":"(.+?) web search is unavailable\\. Configure its credentials or select the automatic provider chain\\.","errorType":"exception","errorClass":"SearchProviderError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/index.ts","lineNumber":197,"sourceCode":"\t} catch {\n\t\t// Preserve the default for one-shot callers that do not initialize Settings.\n\t}\n\n\tconst failures: Array<{ provider: Pick<SearchProvider, \"id\" | \"label\">; error: unknown }> = [];\n\tlet availableProviderCount = 0;\n\tlet lastProvider: Pick<SearchProvider, \"id\" | \"label\"> | undefined;\n\tfor (const candidate of candidates) {\n\t\tlet provider: SearchProvider | undefined;\n\t\tconst providerMeta = { id: candidate.id, label: getSearchProviderLabel(candidate.id) };\n\t\tlastProvider = providerMeta;\n\t\ttry {\n\t\t\tprovider = await getSearchProvider(candidate.id);\n\t\t\tconst available = candidate.explicit\n\t\t\t\t? await provider.isExplicitlyAvailable(authStorage)\n\t\t\t\t: await provider.isAvailable(authStorage);\n\t\t\tif (!available && !candidate.explicit) continue;\n\t\t\tif (!available && candidate.explicit) {\n\t\t\t\tthrow new SearchProviderError(\n\t\t\t\t\tprovider.id,\n\t\t\t\t\t`${provider.label} web search is unavailable. Configure its credentials or select the automatic provider chain.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tavailableProviderCount++;\n\t\t\tlastProvider = provider;\n\n\t\t\tconst response = await provider.search({\n\t\t\t\tquery: params.query,\n\t\t\t\tparsedQuery,\n\t\t\t\tlimit: params.limit,\n\t\t\t\trecency: params.recency,\n\t\t\t\tsystemPrompt: webSearchSystemPrompt,\n\t\t\t\tmaxOutputTokens: params.max_tokens,\n\t\t\t\tnumSearchResults: params.num_search_results,\n\t\t\t\ttemperature: params.temperature,\n\t\t\t\tsignal,\n\t\t\t\ttimeoutMs,","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/index.ts#L179-L215","documentation":"executeSearch walks a chain of candidate search providers; if the caller explicitly requested a specific provider (candidate.explicit) but that provider reports it is not explicitly available (no credentials configured in AuthStorage), it throws SearchProviderError with this message. Automatic-chain candidates are simply skipped; explicit ones fail hard.","triggerScenarios":"Calling runSearchQuery/execute with an explicit provider id (e.g. 'anthropic' or 'brave') whose API key/credentials are missing from auth storage.","commonSituations":"Config file or CLI flag pins a search provider that was never configured; API key removed or rotated out of the auth storage; fresh install without provider setup.","solutions":["Configure credentials for the requested provider (set its API key via auth storage / onboarding).","Switch to the automatic provider chain (omit the explicit provider id) so available providers are picked automatically.","Verify with provider.isAvailable()/isExplicitlyAvailable(authStorage) before requesting an explicit provider.","Check env vars/config for the provider (e.g. ANTHROPIC_API_KEY, BRAVE_API_KEY) are set in the environment the agent runs in."],"exampleFix":"// before\nawait runSearchQuery(params, { authStorage }); // explicit provider 'brave' with no key\n// after\nconst brave = await getSearchProvider(\"brave\");\nif (await brave.isExplicitlyAvailable(authStorage)) {\n  await runSearchQuery({ ...params, provider: \"brave\" }, { authStorage });\n} else {\n  await runSearchQuery(params, { authStorage }); // automatic chain\n}","handlingStrategy":"fallback","validationCode":"const provider = await getSearchProvider(id);\nif (!(await provider.isExplicitlyAvailable(authStorage))) {\n  throw new Error(`${provider.label} not configured — falling back to automatic chain`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  return await runSearchQuery({ ...params, provider: explicitId }, opts);\n} catch (e) {\n  if (e instanceof SearchProviderError && /unavailable/.test(e.message)) {\n    return await runSearchQuery(params, opts); // automatic chain\n  }\n  throw e;\n}","preventionTips":["Check isExplicitlyAvailable/isAvailable before pinning a provider.","Prefer the automatic provider chain unless a specific provider is required.","Keep provider API keys in auth storage and verify them after rotations.","Fail with an actionable message telling the user which credentials to configure."],"tags":["configuration","credentials","search-provider"],"backgroundTag":"missing-api-key","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}