{"record":{"id":"d68332ffb62b6fb4","repo":"wandb/openui","slug":"msg","errorCode":null,"errorMessage":"msg","messagePattern":"msg","errorType":"http","errorClass":"HTTPException","httpStatus":null,"severity":"error","filePath":"backend/openui/server.py","lineNumber":215,"sourceCode":"                    **data,\n                )\n\n                def gen():\n                    return openai_stream_generator(response, input_tokens, user_id, 0)\n\n            return StreamingResponse(gen(), media_type=\"text/event-stream\")\n        elif data.get(\"model\").startswith(\"dummy\"):\n            return StreamingResponse(\n                DummyStreamGenerator(data), media_type=\"text/event-stream\"\n            )\n        raise HTTPException(status=404, detail=\"Invalid model\")\n    except (ResponseError, APIStatusError) as e:\n        traceback.print_exc()\n        logger.exception(\"Known Error: %s\", str(e))\n        msg = str(e)\n        if hasattr(e, \"message\"):\n            msg = e.message\n        raise HTTPException(status_code=e.status_code, detail=msg)\n\n\n@app.exception_handler(RequestValidationError)\n@app.exception_handler(ValidationError)\nasync def validation_exception_handler(\n    request: Request, exc: RequestValidationError | ValidationError\n):\n    body = hasattr(exc, \"body\") and exc.body or None\n    logger.exception(\"Validation Error: %s\", exc)\n    traceback.print_exc()\n    return JSONResponse(\n        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n        content=jsonable_encoder(\n            {\n                \"error\": {\n                    \"code\": \"validation_error\",\n                    \"message\": exc.errors(),\n                    \"body\": body,","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/wandb/openui/blob/42d7ab4ab6650433486dfb12eb3783c393a3e475/backend/openui/server.py#L197-L233","documentation":"This is the generic re-raise path for known LLM provider errors in chat_completions: when the provider SDK raises ResponseError or APIStatusError, the endpoint logs it and re-raises it as an HTTPException with the provider's status_code and message. The 'msg' detail is whatever str(e) or e.message contained, so the text varies by provider (rate limit, invalid key, context length, etc.).","triggerScenarios":"Any provider call inside chat_completions (OpenAI/Groq/LiteLLM/Ollama) that raises ResponseError or APIStatusError — e.g. 401 invalid API key, 429 rate limit, 400 bad request or context-length overflow from the upstream API.","commonSituations":"Exhausted rate limits during batch generation, revoked or expired API keys, sending prompts longer than the model's context window, or provider outages returning 5xx that the SDK surfaces as APIStatusError.","solutions":["Read the detail message and status_code in the HTTP 4xx/5xx response — they come straight from the provider and indicate the specific fix.","For 401: rotate/repair the provider API key in the environment and restart.","For 429: back off and retry with exponential delay, or lower request concurrency.","For 400 context-length errors: shorten the prompt/history or switch to a larger-context model.","Check provider status pages if the status code is 5xx."],"exampleFix":"// before (catching raw HTTPException gives little structure)\ntry:\n    await generate(req)\nexcept Exception:\n    retry()\n// after\ntry:\n    await generate(req)\nexcept HTTPException as e:\n    if e.status_code == 429:\n        await asyncio.sleep(backoff)\n        retry()\n    else:\n        raise","handlingStrategy":"retry","validationCode":"def is_retryable(status: int) -> bool:\n    return status == 429 or status >= 500","typeGuard":null,"tryCatchPattern":"try:\n    resp = await client.post(\"/chat/completions\", json=payload)\n    resp.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    detail = e.response.json().get(\"detail\", \"\")\n    if e.response.status_code == 429:\n        await asyncio.sleep(min(2 ** attempt, 30))\n        continue  # retry with backoff\n    elif e.response.status_code == 401:\n        rotate_api_key()\n    elif e.response.status_code == 400 and \"context\" in detail:\n        payload = truncate_payload(payload)\n        continue\n    else:\n        raise","preventionTips":["Respect provider rate limits with client-side throttling","Count tokens before sending to stay under the model context window","Monitor provider status pages and alert on 5xx spikes","Rotate API keys before expiry and verify them at startup"],"tags":["httpexception","provider-error","rate-limit","fastapi"],"backgroundTag":"upstream-api-error","analyzedSha":"42d7ab4ab6650433486dfb12eb3783c393a3e475","analyzedAt":"2026-09-01T05:00:32.200Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}