vxcontrol/pentagi · error · FatalError
unexpected status code: %d
Error message
unexpected status code: %d
What it means
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.
Source
Thrown at backend/pkg/tools/searchers/firecrawl.go:213
return "", Fatal(fmt.Errorf("the endpoint requested is hidden for administrators only"))
case http.StatusNotFound:
return "", Fatal(fmt.Errorf("the specified endpoint could not be found"))
case http.StatusMethodNotAllowed:
return "", Fatal(fmt.Errorf("there need to try to access an endpoint with an invalid method"))
case http.StatusRequestTimeout:
return "", Retryable(fmt.Errorf("the request timed out. try again later"), 0)
case http.StatusTooManyRequests:
return "", Retryable(fmt.Errorf("there are requesting too many results"), 0)
case http.StatusInternalServerError:
return "", Retryable(fmt.Errorf("there had a problem with our server. try again later"), 0)
case http.StatusBadGateway:
return "", Retryable(fmt.Errorf("there was a problem with the server. Please try again later"), 0)
case http.StatusServiceUnavailable:
return "", Retryable(fmt.Errorf("there are temporarily offline for maintenance. please try again later"), 0)
case http.StatusGatewayTimeout:
return "", Retryable(fmt.Errorf("there are temporarily offline for maintenance. please try again later"), 0)
default:
return "", Fatal(fmt.Errorf("unexpected status code: %d", resp.StatusCode))
}
}
func (f *firecrawl) buildFirecrawlResult(ctx context.Context, query string, result *firecrawlSearchResult) string {
var writer strings.Builder
writer.WriteString("# Links\n\n")
isMarkdownExists := false
for i, res := range result.Data.Web {
writer.WriteString(fmt.Sprintf("## %d. %s\n\n", i+1, res.resolvedTitle()))
writer.WriteString(fmt.Sprintf("* URL %s\n\n", res.resolvedURL()))
if res.Description != "" {
writer.WriteString(fmt.Sprintf("### Short content\n\n%s\n\n", res.Description))
}
if res.Markdown != "" {
isMarkdownExists = true
}
}View on GitHub (pinned to ea665308ba)
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
Example fix
// before: unmapped status kills the engine silently
return "", Fatal(fmt.Errorf("unexpected status code: %d", resp.StatusCode))
// after: classify 5xx as retryable before the default
if resp.StatusCode >= 500 {
return "", Retryable(fmt.Errorf("firecrawl server error: %d", resp.StatusCode), 0)
}
return "", Fatal(fmt.Errorf("unexpected status code: %d", resp.StatusCode)) Defensive patterns
Strategy: fallback
Validate before calling
// preflight the endpoint version resp, _ := http.Post(baseURL+"/v2/search", "application/json", body) // a 404 here means FIRECRAWL_API_URL or the API version is wrong — fix before calling the tool
Try / catch
result, err := searcher.Handle(ctx, req)
if err != nil && searchers.IsFatal(err) && strings.Contains(err.Error(), "unexpected status code") {
log.Warnf("firecrawl unmapped status: %v", err)
return fallbackSearcher.Handle(ctx, req)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to create http client: %w
- failed to build request: %v
- request failed: %s
- request failed
- unexpected status code: %d
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/193bfade832e765b.
Report an issue: GitHub.