Skip to content

fix(proxy): log alias model mismatch at debug, not warning#21749

Open
Elliot0122 wants to merge 2 commits intoBerriAI:mainfrom
Elliot0122:fix/proxy-alias-model-mismatch-warning
Open

fix(proxy): log alias model mismatch at debug, not warning#21749
Elliot0122 wants to merge 2 commits intoBerriAI:mainfrom
Elliot0122:fix/proxy-alias-model-mismatch-warning

Conversation

@Elliot0122
Copy link

Type

🐛 Bug Fix

Changes

When a proxy model alias maps to an upstream model (e.g. "my-alias"
"hosted_vllm/llama-3"), the downstream response carries the upstream model
name. Previously this triggered a WARNING log on every request even though
the mismatch was expected.

_override_openai_response_model now accepts an optional upstream_model
parameter. If the downstream model matches the upstream model, the override
logs at DEBUG instead of WARNING. Genuine unexpected mismatches still log
at WARNING.

Also fixes a pre-existing pyright type narrowing error in
_handle_llm_api_exception for httpx.HTTPStatusError (was blocking commit
via pre-commit hook).

Also fix pre-existing pyright type narrowing error in _handle_llm_api_exception for httpx.HTTPStatusError.
@vercel
Copy link

vercel bot commented Feb 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Feb 21, 2026 8:46am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 21, 2026

Greptile Summary

This PR adds an upstream_model parameter to _override_openai_response_model so that when the downstream response model matches the known upstream model (i.e., a model alias mapping), the log level is DEBUG instead of WARNING. Genuine unexpected mismatches (where upstream_model is None or doesn't match) log at WARNING. The PR also includes a pyright type-narrowing fix for httpx.HTTPStatusError handling in _handle_llm_api_exception.

  • The upstream_model approach is sound for distinguishing expected alias mismatches from unexpected ones
  • The pyright fix (reassigning e to a typed local variable) is a clean workaround for type narrowing
  • Inconsistency: The dict branch of _override_openai_response_model (line 290-300) still uses debug for all mismatches, while the object branch now uses conditional warning/debug — the upstream_model check should be applied to both branches for consistent behavior
  • Tests are well-written, use proper mocking, and make no network calls

Confidence Score: 3/5

  • Low risk overall — changes are limited to logging behavior and a type narrowing fix, but the inconsistency between dict and object branches should be addressed.
  • The core logic change (adding upstream_model parameter) is correct and well-tested, but the dict branch inconsistency means the same mismatch scenario will produce different log levels depending on the response object type. The pyright fix is clean. Tests cover the new functionality thoroughly.
  • Pay attention to litellm/proxy/common_request_processing.py — the dict branch (line 290-300) doesn't apply the upstream_model check, creating an inconsistency with the object branch.

Important Files Changed

Filename Overview
litellm/proxy/common_request_processing.py Adds upstream_model parameter to _override_openai_response_model to distinguish known alias mismatches (DEBUG) from unexpected ones (WARNING). Also fixes pyright type narrowing for httpx.HTTPStatusError. The dict branch has an inconsistency — it doesn't apply the same upstream_model check, leading to different log levels for the same logical mismatch depending on response type.
tests/test_litellm/proxy/test_common_request_processing.py Adds four well-structured mock-only tests covering the new upstream_model parameter: known alias (debug), unknown mismatch (warning), no upstream model (warning), and no mismatch (no logging). All tests use proper mocking with no network calls.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["_override_openai_response_model called"] --> B{requested_model falsy?}
    B -->|Yes| Z[Return early]
    B -->|No| C{Fallback detected?}
    C -->|Yes| Z
    C -->|No| D{response_obj is dict?}
    D -->|Yes| E{downstream != requested?}
    E -->|Yes| F["LOG: DEBUG (always)"]
    E -->|No| G["Set dict model → requested"]
    F --> G
    G --> Z
    D -->|No| H{has model attr?}
    H -->|No| I["LOG: ERROR"]
    I --> Z
    H -->|Yes| J{downstream != requested?}
    J -->|No| K["setattr model → requested"]
    J -->|Yes| L{upstream_model provided AND downstream == upstream?}
    L -->|Yes| M["LOG: DEBUG (known alias)"]
    L -->|No| N["LOG: WARNING (unexpected mismatch)"]
    M --> K
    N --> K
Loading

Last reviewed commit: 4b3cb5e

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +320 to +326
else:
verbose_proxy_logger.warning(
"%s: response model mismatch - requested=%r downstream=%r. Overriding response.model to requested model.",
log_context,
requested_model,
downstream_model,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-introduces WARNING that was intentionally removed

PR #20994 (commit a2e9e73b6) deliberately changed all model-mismatch logs from WARNING to DEBUG because high-traffic customers using model aliases were generating millions of warnings per day, flooding logs and causing disk space issues.

This PR re-introduces WARNING for the non-alias mismatch case (when upstream_model is None or doesn't match downstream_model). However, many legitimate scenarios produce this mismatch without an upstream_model being available — e.g., the streaming path in proxy_server.py:5059 doesn't pass upstream_model at all.

Consider whether the WARNING reintroduction here is intentional, given the history of #20994. If it is, the streaming path in proxy_server.py should also be updated for consistency.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 21, 2026

Additional Comments (1)

litellm/proxy/common_request_processing.py
Dict branch not updated with upstream_model logic

The dict response branch (lines 290-300) still logs all mismatches at DEBUG without checking upstream_model. If the intent is to distinguish known-alias mismatches from unexpected ones, this branch has the same gap. Currently, a dict response with an unexpected mismatch would silently log at DEBUG while an object response would log at WARNING, creating inconsistent observability.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 21, 2026

Additional Comments (1)

litellm/proxy/common_request_processing.py
Inconsistent log level between dict and object branches

The dict branch here always logs at debug for any mismatch, while the object branch below (line 312-326) now conditionally logs at warning when upstream_model is not provided or doesn't match. This means the same logical mismatch will produce different log levels depending on whether response_obj is a dict or an object.

If the intent is to surface genuine unexpected mismatches at warning, the upstream_model check should also be applied here for consistency:

    if isinstance(response_obj, dict):
        downstream_model = response_obj.get("model")
        if downstream_model != requested_model:
            if upstream_model and downstream_model == upstream_model:
                verbose_proxy_logger.debug(
                    "%s: response model is known alias (dict) - requested=%r upstream=%r downstream=%r. Overriding response['model'].",
                    log_context,
                    requested_model,
                    upstream_model,
                    downstream_model,
                )
            else:
                verbose_proxy_logger.warning(
                    "%s: response model mismatch - requested=%r downstream=%r. Overriding response['model'] to requested model.",
                    log_context,
                    requested_model,
                    downstream_model,
                )
        response_obj["model"] = requested_model
        return

@shin-bot-litellm
Copy link
Contributor

Review

1. Does this PR fix the issue it describes?
Yes. Reduces log noise — model alias mismatches now log at DEBUG instead of WARNING when the mismatch is expected (alias → upstream model).

2. Has this issue already been solved elsewhere?
No — the logging was overly aggressive.

3. Are there other PRs addressing the same problem?
No duplicates found.

4. Are there other issues this potentially closes?
Noisy WARNING logs for alias users.

✅ LGTM — also fixes a pyright type error as bonus.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants