can1357/oh-my-pi · error

Unknown search provider: ${id}

Error message

Unknown search provider: ${id}

What it means

getSearchProvider resolves a provider id (e.g. 'brave', 'anthropic') from the PROVIDER_META registry, instantiates and caches it. If the id is not a key of PROVIDER_META it throws 'Unknown search provider: <id>'. This is an invalid-identifier error protecting against typos and stale provider ids.

Source

Thrown at packages/coding-agent/src/web/search/provider.ts:185

}

/** Format the ordered provider fallback failures for terminal/tool output. */
export function formatSearchProviderFailures(
	failures: readonly { provider: Pick<SearchProvider, "id" | "label">; error: unknown }[],
): string {
	return failures.map(f => `${f.provider.id}: ${formatSearchProviderFailure(f.error, f.provider)}`).join("; ");
}

/**
 * Resolve and cache a provider instance. First call for a given id loads the
 * underlying module; subsequent calls return the cached singleton.
 */
export async function getSearchProvider(id: SearchProviderId): Promise<SearchProvider> {
	const cached = instanceCache.get(id);
	if (cached) return cached;
	const meta = PROVIDER_META[id];
	if (!meta) {
		throw new Error(`Unknown search provider: ${id}`);
	}
	const provider = await meta.load();
	instanceCache.set(id, provider);
	return provider;
}

/** Provider fallback order set via settings (default: built-in order). */
let orderedProvIds: readonly SearchProviderId[] = SEARCH_PROVIDER_ORDER;
/** Providers the user explicitly listed in `providers.webSearchOrder`. */
let explicitProvIds = new Set<SearchProviderId>();

/**
 * Prioritize configured providers while retaining every unlisted provider in
 * its built-in relative order. Invalid IDs are ignored defensively. Listed
 * providers are treated as explicit selections: they resolve through
 * `isExplicitlyAvailable`, so e.g. a hand-listed Perplexity may fall back to
 * anonymous search exactly like the retired single-preference setting did.
 */

View on GitHub (pinned to 9690622007)

Solutions

  1. Use a valid provider id from the SearchProviderId type / PROVIDER_META keys.
  2. Validate user/config-supplied provider names against the allowed id list before calling.
  3. Update configs after upgrades that rename or remove providers.
  4. Narrow with the SearchProviderId type so invalid ids are caught at compile time.

Example fix

// before
const p = await getSearchProvider(userInput.provider); // 'google' not registered
// after
const VALID = ["brave", "anthropic"] as const;
if (!VALID.includes(userInput.provider as never)) {
  throw new Error(`provider must be one of: ${VALID.join(", ")}`);
}
const p = await getSearchProvider(userInput.provider as SearchProviderId);
Defensive patterns

Strategy: validation

Validate before calling

const PROVIDER_IDS = ["brave", "anthropic"] as const; // mirror SearchProviderId
type ProviderId = (typeof PROVIDER_IDS)[number];
function isValidProviderId(x: string): x is ProviderId {
  return (PROVIDER_IDS as readonly string[]).includes(x);
}
if (!isValidProviderId(config.provider)) throw new Error(`Unknown provider: ${config.provider}`);

Type guard

function isSearchProviderId(x: string): x is SearchProviderId {
  return x in PROVIDER_META; // same registry the loader consults
}

Try / catch

try { const p = await getSearchProvider(id); }
catch (e) {
  if (e instanceof Error && e.message.startsWith("Unknown search provider:")) {
    return { content: [{ type: "text", text: `Provider '${id}' is not available. Valid: brave, anthropic` }] };
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing an unregistered id (typo, removed/renamed provider, user-supplied string from config) to getSearchProvider or as the explicit provider in runSearchQuery.

Common situations: Typo in config ('Brave' vs 'brave'); provider removed after an upgrade so old configs reference a deleted id; programmatically building ids from unvalidated user input.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d6f02429e9ad806e. Report an issue: GitHub.