{"record":{"id":"193bfade832e765b","repo":"vxcontrol/pentagi","slug":"unexpected-status-code-d-193bfa","errorCode":null,"errorMessage":"unexpected status code: %d","messagePattern":"unexpected status code: (.+?)","errorType":"exception","errorClass":"FatalError","httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/searchers/firecrawl.go","lineNumber":213,"sourceCode":"\t\treturn \"\", Fatal(fmt.Errorf(\"the endpoint requested is hidden for administrators only\"))\n\tcase http.StatusNotFound:\n\t\treturn \"\", Fatal(fmt.Errorf(\"the specified endpoint could not be found\"))\n\tcase http.StatusMethodNotAllowed:\n\t\treturn \"\", Fatal(fmt.Errorf(\"there need to try to access an endpoint with an invalid method\"))\n\tcase http.StatusRequestTimeout:\n\t\treturn \"\", Retryable(fmt.Errorf(\"the request timed out. try again later\"), 0)\n\tcase http.StatusTooManyRequests:\n\t\treturn \"\", Retryable(fmt.Errorf(\"there are requesting too many results\"), 0)\n\tcase http.StatusInternalServerError:\n\t\treturn \"\", Retryable(fmt.Errorf(\"there had a problem with our server. try again later\"), 0)\n\tcase http.StatusBadGateway:\n\t\treturn \"\", Retryable(fmt.Errorf(\"there was a problem with the server. Please try again later\"), 0)\n\tcase http.StatusServiceUnavailable:\n\t\treturn \"\", Retryable(fmt.Errorf(\"there are temporarily offline for maintenance. please try again later\"), 0)\n\tcase http.StatusGatewayTimeout:\n\t\treturn \"\", Retryable(fmt.Errorf(\"there are temporarily offline for maintenance. please try again later\"), 0)\n\tdefault:\n\t\treturn \"\", Fatal(fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode))\n\t}\n}\n\nfunc (f *firecrawl) buildFirecrawlResult(ctx context.Context, query string, result *firecrawlSearchResult) string {\n\tvar writer strings.Builder\n\twriter.WriteString(\"# Links\\n\\n\")\n\n\tisMarkdownExists := false\n\tfor i, res := range result.Data.Web {\n\t\twriter.WriteString(fmt.Sprintf(\"## %d. %s\\n\\n\", i+1, res.resolvedTitle()))\n\t\twriter.WriteString(fmt.Sprintf(\"* URL %s\\n\\n\", res.resolvedURL()))\n\t\tif res.Description != \"\" {\n\t\t\twriter.WriteString(fmt.Sprintf(\"### Short content\\n\\n%s\\n\\n\", res.Description))\n\t\t}\n\t\tif res.Markdown != \"\" {\n\t\t\tisMarkdownExists = true\n\t\t}\n\t}","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/searchers/firecrawl.go#L195-L231","documentation":"parseHTTPResponse's default branch fires when Firecrawl returns an HTTP status the switch does not explicitly handle (anything other than 200, 400, 401, 402, 403, 404, 405, 408, 429, 500, 502, 503, 504). It is classified Fatal, so the orchestrator will not retry this engine for the query. The message includes the raw status code for diagnosis.","triggerScenarios":"Any unmapped status from POST /v2/search, e.g. 402-adjacent plan/quota variants, 413 from oversized payloads, 418/4xx WAF challenges, 301/302 not followed, or a self-hosted FIRECRAWL_API_URL returning a reverse-proxy-specific status.","commonSituations":"Misconfigured FIRECRAWL_API_URL hitting a login page (302/401 variant) or wrong path; API version drift after Firecrawl changes /v2 behavior; corporate proxy returning 407; WAF/CDN blocking the request with 4xx codes not in the switch.","solutions":["Read the status code in the message and check the response body/logs for the real cause","Verify FIRECRAWL_API_URL points to the correct base (search path /v2/search is appended automatically; do not include it)","Confirm the Firecrawl account/plan supports the search endpoint (402/403-adjacent statuses) and the API key is valid","Update the switch in parseHTTPResponse to map newly observed statuses to Retryable/Fatal appropriately","If caused by a proxy/WAF, whitelist the backend egress or route Firecrawl traffic outside the proxy"],"exampleFix":"// before: unmapped status kills the engine silently\nreturn \"\", Fatal(fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode))\n// after: classify 5xx as retryable before the default\nif resp.StatusCode >= 500 {\n    return \"\", Retryable(fmt.Errorf(\"firecrawl server error: %d\", resp.StatusCode), 0)\n}\nreturn \"\", Fatal(fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode))","handlingStrategy":"fallback","validationCode":"// preflight the endpoint version\nresp, _ := http.Post(baseURL+\"/v2/search\", \"application/json\", body)\n// a 404 here means FIRECRAWL_API_URL or the API version is wrong — fix before calling the tool","typeGuard":null,"tryCatchPattern":"result, err := searcher.Handle(ctx, req)\nif err != nil && searchers.IsFatal(err) && strings.Contains(err.Error(), \"unexpected status code\") {\n    log.Warnf(\"firecrawl unmapped status: %v\", err)\n    return fallbackSearcher.Handle(ctx, req)\n}","preventionTips":["Pin/verify the Firecrawl API version (v2) and FIRECRAWL_API_URL base (no path suffix)","Keep parseHTTPResponse's status switch updated when upgrading Firecrawl","Log response bodies for unmapped statuses to speed diagnosis"],"tags":["http","firecrawl","unmapped-status","fatal"],"backgroundTag":"unexpected-http-status-code","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}