{"record":{"id":"987d89374c069f50","repo":"can1357/oh-my-pi","slug":"smithery-search-failed-with-status-response-stat","errorCode":null,"errorMessage":"Smithery search failed with status ${response.status}","messagePattern":"Smithery search failed with status (.+?)","errorType":"http","errorClass":"SmitheryRegistryError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/mcp/smithery-registry.ts","lineNumber":435,"sourceCode":"\tfor (let page = 1; page <= maxPages; page++) {\n\t\tconst url = new URL(`${SMITHERY_REGISTRY_BASE_URL}/servers`);\n\t\turl.searchParams.set(\"q\", query);\n\t\turl.searchParams.set(\"pageSize\", String(pageSize));\n\t\tif (page > 1) url.searchParams.set(\"page\", String(page));\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetch(url.toString(), {\n\t\t\t\theaders,\n\t\t\t\tsignal: withTimeoutSignal(SMITHERY_REGISTRY_TIMEOUT_MS, options?.signal),\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tif (isTimeoutError(err)) {\n\t\t\t\tthrow new SmitheryRegistryError(\"Smithery search timed out after 10s\", 0);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t\tif (!response.ok) {\n\t\t\tthrow new SmitheryRegistryError(`Smithery search failed with status ${response.status}`, response.status);\n\t\t}\n\t\tconst payload = (await response.json()) as { servers?: SmitherySearchEntry[] };\n\t\tconst pageEntries = payload.servers ?? [];\n\t\tif (pageEntries.length === 0) break;\n\t\tallEntries.push(...pageEntries);\n\n\t\t// Stop early if we already have enough identity-matching entries.\n\t\tconst filtered = isSemantic ? allEntries : allEntries.filter(entry => matchesIdentityQuery(query, entry));\n\t\tif (filtered.length >= limit * 2) break;\n\t\tif (pageEntries.length < pageSize) break;\n\t}\n\n\tconst entries = isSemantic ? [...allEntries] : [...allEntries].filter(entry => matchesIdentityQuery(query, entry));\n\n\t// Only apply local useCount sort when not in semantic mode (preserve API relevance ranking).\n\tif (!isSemantic) {\n\t\tentries.sort((a, b) => (b.useCount ?? 0) - (a.useCount ?? 0));\n\t}","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/mcp/smithery-registry.ts#L417-L453","documentation":"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.","triggerScenarios":"Calling searchSmitheryRegistry (directly or via #validateSmitheryApiKey) when the search API responds 401 (bad/missing API key), 429 (too many requests), or 5xx (server error).","commonSituations":"Invalid or revoked SMITHERY_API_KEY (401) — very common when validating keys; searching in a tight loop causing 429; Smithery outage causing 5xx.","solutions":["If status is 401/403: re-authenticate with Smithery (login flow) or set a valid SMITHERY_API_KEY from the dashboard","If 429: back off and retry after a delay; reduce search frequency","If 5xx: retry later or check the Smithery status page","Verify network access to the registry endpoint if failures persist"],"exampleFix":"// before: treating all failures the same\nawait searchSmitheryRegistry({ query });\n// after: branch on status\ntry {\n  await searchSmitheryRegistry({ query });\n} catch (e) {\n  if (e instanceof SmitheryRegistryError && (e.status === 401 || e.status === 403)) {\n    await promptSmitheryLogin();\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"// verify the key is present before registry calls that validate auth\nconst key = process.env.SMITHERY_API_KEY?.trim();\nif (!key) throw new Error(\"SMITHERY_API_KEY not set — search will 401\");","typeGuard":"function isSmitheryRegistryError(err: unknown): err is SmitheryRegistryError {\n  return err instanceof SmitheryRegistryError && typeof err.status === \"number\";\n}","tryCatchPattern":"try {\n  const entries = await searchSmitheryRegistry({ query });\n} catch (err) {\n  if (isSmitheryRegistryError(err)) {\n    if (err.status === 401 || err.status === 403) await runSmitheryLogin();\n    else if (err.status === 429) await Bun.sleep(5000);\n    else throw err;\n  } else throw err;\n}","preventionTips":["Validate the API key once at startup (a cheap registry call) instead of failing mid-search","Throttle search frequency to avoid 429s","Branch on err.status: 401→re-auth, 429→backoff, 5xx→retry later","Keep SMITHERY_API_KEY current; revoked keys surface here first"],"tags":["http","smithery","registry","api-key"],"backgroundTag":"http-api-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}