HKUDS/DeepTutor · error · LLMAPIError

OpenAI API error: {error_text}

Error message

OpenAI API error: {error_text}

What it means

Raised inside _openai_complete when the OpenAI-compatible endpoint returns a non-2xx status after the retry/retry-after handling branch did not apply. The raw response body (error_text) is embedded in the LLMAPIError along with status_code and provider, so the message mirrors whatever the server returned (e.g. 401 invalid key, 400 bad request, 429 exhausted).

Source

Thrown at deeptutor/services/llm/cloud_provider.py:426

                                    if isinstance(first_choice, Mapping):
                                        message = cast(Mapping[str, object], first_choice).get(
                                            "message"
                                        )
                                    else:
                                        message = None
                                    if isinstance(message, Mapping):
                                        content = extract_response_content(
                                            cast(dict[str, object], message)
                                        )
                            else:
                                retry_text = await retry_resp.text()
                                raise LLMAPIError(
                                    f"OpenAI API error: {retry_text}",
                                    status_code=retry_resp.status,
                                    provider=binding or "openai",
                                )
                    else:
                        raise LLMAPIError(
                            f"OpenAI API error: {error_text}",
                            status_code=resp.status,
                            provider=binding or "openai",
                        )
        except aiohttp.ClientError as e:
            # Handle connection errors with more specific messages
            if "forcibly closed" in str(e).lower() or "10054" in str(e):
                raise LLMAPIError(
                    f"Connection to {binding} API was forcibly closed. "
                    "This may indicate network issues or server-side problems. "
                    "Please check your internet connection and try again.",
                    status_code=0,
                    provider=binding or "openai",
                ) from e
            else:
                raise LLMAPIError(
                    f"Network error connecting to {binding} API: {e}",
                    status_code=0,

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Read status_code and error_text from the LLMAPIError to see the server's own message.
  2. Fix the underlying cause: correct base_url, valid model name for that endpoint, valid API key.
  3. If the error mentions response_format, remove it or rely on the runtime disable_response_format_at_runtime retry.
  4. For 429/5xx, add backoff retries at the caller or use KeyPool rotation.

Example fix

// before
resp = await complete(prompt=p, model=m, base_url="http://localhost:8000")

# after
try:
    resp = await complete(prompt=p, model=m, base_url="http://localhost:8000/v1")
except LLMAPIError as e:
    if e.status_code == 404:
        raise RuntimeError(f"Bad base_url or model: {e}") from e
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

# Not fully avoidable: server-side decision. Pre-check what you control:
assert (model or "").strip(), "model required"
assert base_url is None or base_url.startswith("http"), "base_url malformed"

Try / catch

try:
    out = await complete(prompt=p, model=m, api_key=k, base_url=u)
except LLMAPIError as e:
    if e.status_code == 401:
        refresh_key()
    elif e.status_code == 429:
        await asyncio.sleep(30)
    else:
        log.error("provider %s status %s: %s", e.provider, e.status_code, e)
        raise

Prevention

When it happens

Trigger: POSTing to an OpenAI-compatible chat completions endpoint that replies 400 (malformed payload/unsupported param), 401/403 (bad key), 404 (wrong base_url path), or 500; using a proxy or local server (vLLM, LM Studio, Ollama's OpenAI shim) that returns an error body.

Common situations: Misconfigured base_url pointing at the wrong path; provider rejects response_format or a tool param; model name not available on the endpoint; expired or revoked API key; reverse proxy returning HTML error pages.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/1c002dda5513092d. Report an issue: GitHub.