{"record":{"id":"d14829c07426805d","repo":"tinyhumansai/openhuman","slug":"mcp-official-registry-returned-http-status","errorCode":null,"errorMessage":"MCP official registry returned HTTP {status}: {}","messagePattern":"MCP official registry returned HTTP (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/openhuman/mcp/registry/registries/mcp_official.rs","lineNumber":272,"sourceCode":"    let client = http_client()?;\n    let url = format!(\"{}/v0/servers\", base_url(config));\n    let mut req = client.get(&url).header(\"Accept\", \"application/json\");\n    if !q.is_empty() {\n        req = req.query(&[(\"search\", q)]);\n    }\n    req = req.query(&[(\"limit\", &limit.to_string())]);\n    if let Some(c) = cursor {\n        req = req.query(&[(\"cursor\", c)]);\n    }\n    req = apply_auth(config, req);\n\n    let resp = req.send().await.context(\"MCP official search failed\")?;\n    let status = resp.status();\n    let body = resp.text().await.context(\"MCP official read failed\")?;\n\n    if !status.is_success() {\n        tracing::warn!(\"[mcp-official] search HTTP {status}\");\n        anyhow::bail!(\n            \"MCP official registry returned HTTP {status}: {}\",\n            &body[..body.len().min(200)]\n        );\n    }\n    Ok(body)\n}\n\n/// Walk the cursor chain forward starting from page 1 until we have the\n/// cursor that, when sent with the next request, produces `target_page`.\n///\n/// Returns `Some(cursor)` to feed into the request for `target_page`, or\n/// `None` if the cursor chain ran out before reaching `target_page`.\n///\n/// Bails after [`MAX_CURSOR_WALK_PAGES`] iterations to keep a single user\n/// request from fanning into hundreds of upstream calls.\nasync fn walk_cursor_for_page(\n    config: &Config,\n    q: &str,","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/mcp/registry/registries/mcp_official.rs#L254-L290","documentation":"A paginated search against the official MCP registry (list/search with `limit` and optional `cursor`) returned a non-2xx; the message includes status plus the first 200 chars of the body, and a `[mcp-official] search HTTP {status}` warn is logged. This is the list/search network call underlying registry browsing.","triggerScenarios":"Registry search when the service is down or rate-limiting (429/5xx), auth failures (401/403) with a configured token, or a malformed cursor supplied by a caller (400).","commonSituations":"Rate limits during aggressive pagination/crawling of the catalog; temporary registry outages; expired registry API token; query strings with special characters hitting a strict gateway.","solutions":["On 429, back off and retry with fewer/longer-interval requests (reduce `limit`, avoid deep pagination).","On 401/403, refresh or clear the registry auth token.","On 5xx, retry after a delay; check the registry status.","If it persists, reproduce with curl using the same query/limit/cursor to isolate."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match search_page(q, limit, cursor).await {\n    Err(e) if e.to_string().contains(\"HTTP 429\") => {\n        backoff_jitter().await;\n        search_page(q, limit, cursor).await\n    }\n    other => other,\n}","preventionTips":["Throttle and space registry searches; avoid crawling all pages rapidly.","Reuse returned cursors instead of re-searching from page 1.","Keep the registry auth token current if authenticated access returns 401/403."],"tags":["mcp","registry","http","search","pagination"],"backgroundTag":"http-error-response","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}