Skip to content

litellm fork: emit OpenAI error code context_length_exceeded on context-window 400s #119

Open

Description

@sre-helmcode

Context

nan-devops#629 makes community return a clear 400 on context-window overflow, with no fallback. Message-based detection works: opencode's patterns and litellm's own detector are tested against every variant.

What's still missing is the OpenAI error code: "context_length_exceeded", which clients that only read code rely on (OpenAI SDK users, Codex-style clients). It can't be set from the usage hook, in litellm 1.83.14 or 1.102.1:

  • ProxyException.__init__ stores the HTTP status in self.code (str(code)).
  • to_dict() emits code, but never emits openai_code.
  • openai_exception_handler derives the HTTP status from int(exc.code), so a non-numeric code would 500.

Options

  1. Patch the fork: have ProxyException.to_dict() emit openai_code as code when set, keeping the HTTP status separate.
  2. Add a custom exception handler.

Either way, add a test in the real-litellm harness (tests/usage-hook/test_context_window_refusal_real_litellm.py).

🤖 Generated with Claude Code

Activity

  1. sre-helmcode commented on Sep 30, 2026

    @sre-helmcode
    ContributorAuthor

    Reopening: nan-devops#641 is deployed, but the code is not effective on community yet.

    • litellm-test (1.102.1-spend-fix.2), direct port-forward: 400 with code: "context_length_exceeded", streamed and non-streamed. ✅
    • community (1.83.14-spend-fix.4, hook 13db736b), direct to the pod: gemma4 overflow gives 400, type: invalid_request_error, but code: "400", streamed and non-streamed. The same happens via api.nan.builders, and the edge Worker is ruled out (the direct pod test gives the same result).
    • In the pod: litellm.proxy._types.StatusWithOpenAICode exists, and /etc/litellm/usage_hook.py contains _cwe_status.

    Hypothesis: in prod, community registers several callbacks (usage_hook, rate_limit_hook, credits/stream-integrity/…). A later failure hook, or litellm 1.83.14's handler on the multi-callback path, rebuilds or replaces the exception or its status as a plain int, and the marker is lost. The real-litellm harness only registers the usage hook. The next step is a harness with the production callback list from values.yaml, on 1.83.14.

    There is no regression: the behaviour is identical to before #641 (clear message, code "400").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions