Skip to content

bug: guard OpenRouter pricing JSON parsing against malformed responses - #46

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1790154094-openrouter-pricing-guard
Open

devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1790154094-openrouter-pricing-guard

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Summary

Code scan finding (low): get_pricing_openrouter() indexed the external OpenRouter catalog JSON directly (model_metadata["data"], model["id"], model["pricing"], float(v)), so any shape change or non-numeric pricing value raised KeyError/ValueError/TypeError out of set_pricing_attributes() and aborted model init — and since the function is @cached, permanently for the process. The sibling pricing functions degrade to {}/0.0 instead.

Now the traversal skips malformed records instead of raising:

model_metadata = response.json()          # wrapped in try/except -> {}
for model in model_metadata.get("data") or []:
    # skip non-dict records, or records missing id/pricing
    pricing[model_id] = {k: c for k, v in model_pricing.items() if (c := _to_float(v)) is not None}

_to_float returns None for non-numeric/None values. set_pricing_attributes() likewise uses _to_float(model_costs.get("prompt"/"completion")) and falls through to the existing litellm lookup when either is missing or non-numeric, instead of KeyErroring on model_costs["prompt"]. Well-formed responses produce the same dict as before. The non-200 raise ValueError is unchanged (a config/auth error, not a parsing one).

Added test_get_pricing_openrouter_malformed_payload covering numeric strings, null pricing values, records missing id/pricing, non-dict records, and a non-dict top-level payload.

Verified: pytest tests/llm/test_tracking.py -m 'not pricy' passes (10 passed, 1 skipped — the live OpenRouter test skips without an API key). black on the two touched files is clean; 7 other files in src/ were already unformatted on main.

Devin-Org: engineering

Link to Devin session: https://app.devin.ai/sessions/736009401ebb43858f8f468588c5cd0b
Open in Devin Desktop: https://app.devin.ai/desktop/session/736009401ebb43858f8f468588c5cd0b?variant=devin


Devin Review

Status Commit
⚪ Not started —

Run Devin Review

Devin Review (Staging)

@devin-ai-integration

Copy link
Copy Markdown
Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

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.

0 participants