wandb/openui · error · HTTPException

msg

Error message

msg

What it means

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.).

Source

Thrown at backend/openui/server.py:215

                    **data,
                )

                def gen():
                    return openai_stream_generator(response, input_tokens, user_id, 0)

            return StreamingResponse(gen(), media_type="text/event-stream")
        elif data.get("model").startswith("dummy"):
            return StreamingResponse(
                DummyStreamGenerator(data), media_type="text/event-stream"
            )
        raise HTTPException(status=404, detail="Invalid model")
    except (ResponseError, APIStatusError) as e:
        traceback.print_exc()
        logger.exception("Known Error: %s", str(e))
        msg = str(e)
        if hasattr(e, "message"):
            msg = e.message
        raise HTTPException(status_code=e.status_code, detail=msg)


@app.exception_handler(RequestValidationError)
@app.exception_handler(ValidationError)
async def validation_exception_handler(
    request: Request, exc: RequestValidationError | ValidationError
):
    body = hasattr(exc, "body") and exc.body or None
    logger.exception("Validation Error: %s", exc)
    traceback.print_exc()
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=jsonable_encoder(
            {
                "error": {
                    "code": "validation_error",
                    "message": exc.errors(),
                    "body": body,

View on GitHub (pinned to 42d7ab4ab6)

Solutions

  1. Read the detail message and status_code in the HTTP 4xx/5xx response — they come straight from the provider and indicate the specific fix.
  2. For 401: rotate/repair the provider API key in the environment and restart.
  3. For 429: back off and retry with exponential delay, or lower request concurrency.
  4. For 400 context-length errors: shorten the prompt/history or switch to a larger-context model.
  5. Check provider status pages if the status code is 5xx.

Example fix

// before (catching raw HTTPException gives little structure)
try:
    await generate(req)
except Exception:
    retry()
// after
try:
    await generate(req)
except HTTPException as e:
    if e.status_code == 429:
        await asyncio.sleep(backoff)
        retry()
    else:
        raise
Defensive patterns

Strategy: retry

Validate before calling

def is_retryable(status: int) -> bool:
    return status == 429 or status >= 500

Try / catch

try:
    resp = await client.post("/chat/completions", json=payload)
    resp.raise_for_status()
except httpx.HTTPStatusError as e:
    detail = e.response.json().get("detail", "")
    if e.response.status_code == 429:
        await asyncio.sleep(min(2 ** attempt, 30))
        continue  # retry with backoff
    elif e.response.status_code == 401:
        rotate_api_key()
    elif e.response.status_code == 400 and "context" in detail:
        payload = truncate_payload(payload)
        continue
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of wandb/openui@42d7ab4ab6 (2026-09-01). Data as JSON: /api/errors/d68332ffb62b6fb4. Report an issue: GitHub.