can1357/oh-my-pi · error · SmitheryRegistryError

Smithery search failed with status ${response.status}

Error message

Smithery search failed with status ${response.status}

What it means

SmitheryRegistryError thrown by searchSmitheryRegistry when the registry search endpoint returns a non-OK HTTP status. The status code is preserved on the error object; 401/403 indicate an invalid Smithery API key, 429 indicates rate limiting, and 5xx indicates a server-side problem.

Source

Thrown at packages/coding-agent/src/mcp/smithery-registry.ts:435

	for (let page = 1; page <= maxPages; page++) {
		const url = new URL(`${SMITHERY_REGISTRY_BASE_URL}/servers`);
		url.searchParams.set("q", query);
		url.searchParams.set("pageSize", String(pageSize));
		if (page > 1) url.searchParams.set("page", String(page));
		let response: Response;
		try {
			response = await fetch(url.toString(), {
				headers,
				signal: withTimeoutSignal(SMITHERY_REGISTRY_TIMEOUT_MS, options?.signal),
			});
		} catch (err) {
			if (isTimeoutError(err)) {
				throw new SmitheryRegistryError("Smithery search timed out after 10s", 0);
			}
			throw err;
		}
		if (!response.ok) {
			throw new SmitheryRegistryError(`Smithery search failed with status ${response.status}`, response.status);
		}
		const payload = (await response.json()) as { servers?: SmitherySearchEntry[] };
		const pageEntries = payload.servers ?? [];
		if (pageEntries.length === 0) break;
		allEntries.push(...pageEntries);

		// Stop early if we already have enough identity-matching entries.
		const filtered = isSemantic ? allEntries : allEntries.filter(entry => matchesIdentityQuery(query, entry));
		if (filtered.length >= limit * 2) break;
		if (pageEntries.length < pageSize) break;
	}

	const entries = isSemantic ? [...allEntries] : [...allEntries].filter(entry => matchesIdentityQuery(query, entry));

	// Only apply local useCount sort when not in semantic mode (preserve API relevance ranking).
	if (!isSemantic) {
		entries.sort((a, b) => (b.useCount ?? 0) - (a.useCount ?? 0));
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. If status is 401/403: re-authenticate with Smithery (login flow) or set a valid SMITHERY_API_KEY from the dashboard
  2. If 429: back off and retry after a delay; reduce search frequency
  3. If 5xx: retry later or check the Smithery status page
  4. Verify network access to the registry endpoint if failures persist

Example fix

// before: treating all failures the same
await searchSmitheryRegistry({ query });
// after: branch on status
try {
  await searchSmitheryRegistry({ query });
} catch (e) {
  if (e instanceof SmitheryRegistryError && (e.status === 401 || e.status === 403)) {
    await promptSmitheryLogin();
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the key is present before registry calls that validate auth
const key = process.env.SMITHERY_API_KEY?.trim();
if (!key) throw new Error("SMITHERY_API_KEY not set — search will 401");

Type guard

function isSmitheryRegistryError(err: unknown): err is SmitheryRegistryError {
  return err instanceof SmitheryRegistryError && typeof err.status === "number";
}

Try / catch

try {
  const entries = await searchSmitheryRegistry({ query });
} catch (err) {
  if (isSmitheryRegistryError(err)) {
    if (err.status === 401 || err.status === 403) await runSmitheryLogin();
    else if (err.status === 429) await Bun.sleep(5000);
    else throw err;
  } else throw err;
}

Prevention

When it happens

Trigger: Calling searchSmitheryRegistry (directly or via #validateSmitheryApiKey) when the search API responds 401 (bad/missing API key), 429 (too many requests), or 5xx (server error).

Common situations: Invalid or revoked SMITHERY_API_KEY (401) — very common when validating keys; searching in a tight loop causing 429; Smithery outage causing 5xx.

Related errors


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