{"record":{"id":"3c2d4081adffd06c","repo":"vxcontrol/pentagi","slug":"unexpected-status-code-d-3c2d40","errorCode":null,"errorMessage":"unexpected status code: %d","messagePattern":"unexpected status code: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/searchers/perplexity.go","lineNumber":239,"sourceCode":"\t\treturn errors.New(\"API key is wrong\")\n\tcase http.StatusForbidden:\n\t\treturn errors.New(\"the endpoint requested is hidden for administrators only\")\n\tcase http.StatusNotFound:\n\t\treturn errors.New(\"the specified endpoint could not be found\")\n\tcase http.StatusMethodNotAllowed:\n\t\treturn errors.New(\"there need to try to access an endpoint with an invalid method\")\n\tcase http.StatusTooManyRequests:\n\t\treturn errors.New(\"there are requesting too many results\")\n\tcase http.StatusInternalServerError:\n\t\treturn errors.New(\"there had a problem with our server. try again later\")\n\tcase http.StatusBadGateway:\n\t\treturn errors.New(\"there was a problem with the server. Please try again later\")\n\tcase http.StatusServiceUnavailable:\n\t\treturn errors.New(\"there are temporarily offline for maintenance. please try again later\")\n\tcase http.StatusGatewayTimeout:\n\t\treturn errors.New(\"there are temporarily offline for maintenance. please try again later\")\n\tdefault:\n\t\treturn fmt.Errorf(\"unexpected status code: %d\", statusCode)\n\t}\n}\n\n// formatResponse formats the API response into readable text\nfunc (p *perplexity) formatResponse(ctx context.Context, response *CompletionResponse, query string) string {\n\tvar builder strings.Builder\n\n\t// Checking for response choices\n\tif len(response.Choices) == 0 {\n\t\treturn \"No response received from Perplexity API\"\n\t}\n\n\t// Getting the response content\n\tcontent := response.Choices[0].Message.Content\n\tbuilder.WriteString(\"# Answer\\n\\n\")\n\tbuilder.WriteString(content)\n\n\t// Adding citations if available and within maxResults limit","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/searchers/perplexity.go#L221-L257","documentation":"handleErrorResponse maps known Perplexity API HTTP status codes to human-readable messages; the default branch produces 'unexpected status code: %d' for any status not in the explicit switch (400, 401, 403, 404, 405, 429, 500, 502, 503, 504). The caller (search) then classifies it: Retryable for 429 or >=500, Fatal otherwise. It signals an API-level failure surfaced through an undocumented status code.","triggerScenarios":"Perplexity returns a status code outside the mapped set, e.g. 402 Payment Required (credits exhausted), 408 Request Timeout, 422 Unprocessable Entity from a malformed request payload, or 418/5xx variants from edge infrastructure.","commonSituations":"Perplexity account out of credits or over quota returning 402; new API version introducing 422 validation errors; Cloudflare/WAF edge returning 520-527 codes not in the switch table.","solutions":["Check the returned status code in the log and look it up in Perplexity's API documentation to identify the specific failure","If it is 402 Payment Required, top up the Perplexity account or check billing/credits","If 422, review the request payload (model name via PERPLEXITY_MODEL, search_context_size values) against current API requirements","Check the search orchestrator fallback — configure an alternative engine (e.g. SearxNG) in fallbackStrategy for resilience","Update the switch in handleErrorResponse to map newly observed status codes to explicit messages"],"exampleFix":"// before\ncase http.StatusGatewayTimeout:\n    return errors.New(\"there are temporarily offline for maintenance. please try again later\")\ndefault:\n    return fmt.Errorf(\"unexpected status code: %d\", statusCode)\n// after\ncase http.StatusGatewayTimeout:\n    return errors.New(\"there are temporarily offline for maintenance. please try again later\")\ncase http.StatusPaymentRequired:\n    return errors.New(\"perplexity credits exhausted: check billing\")\ndefault:\n    return fmt.Errorf(\"unexpected status code: %d\", statusCode)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"result, err := searcher.Handle(ctx, req)\nvar fatal FatalError\nif err != nil {\n    if errors.As(err, &fatal) {\n        log.Printf(\"perplexity fatal error: %v\", err) // switch engine\n    } else {\n        log.Printf(\"perplexity retryable error: %v\", err) // retry/backoff\n    }\n    result, err = fallbackSearcher.Handle(ctx, req)\n}","preventionTips":["Keep fallback search engines configured in the web_search fallbackStrategy chain","Monitor Perplexity account credits/billing (402 is unmapped and lands here)","Record the status code in metrics to catch new/unmapped codes early","Validate request payload params (model, context size) against current API docs"],"tags":["http","http-status","perplexity","api"],"backgroundTag":"unexpected-http-status","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}