Skip to content

fix(guardrails): treat an unknown straiker api_version as unset instead of skipping the guardrail - #43956

Merged
yucheng-berri merged 4 commits into
mainfrom
litellm_straiker_unknown_api_version_unset
Oct 1, 2026
Merged

yucheng-berri merged 4 commits into
mainfrom
litellm_straiker_unknown_api_version_unset

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • A Straiker guardrail with a stray api_version is silently dropped at startup
  • The proxy then serves every request with no Straiker check

How it solves it:

  • An unknown api_version from config now logs a warning and counts as unset
  • The route then follows the key prefix: sk_agt_ keys go to v3, others to v1
  • v1, v3 and unset behave exactly as before

User Flow

Before: an admin whose Straiker config carries a leftover api_version (for example "2024-09-01" copied from an Azure Content Safety block, or "") loses the guardrail without noticing

  1. The admin starts the proxy with a Straiker guardrail that has api_version: "2024-09-01"
  2. Startup logs Skipping guardrail 'straiker': invalid configuration, proxy is starting WITHOUT this guardrail and the proxy comes up healthy
  3. The developer sends POST https://litellm-domain/v1/chat/completions with a prompt injection and "guardrails": ["straiker"]
  4. The request goes straight to the model and returns 200, Straiker is never called

After: the same config keeps the guardrail on and the injection is blocked

  1. The admin starts the proxy with the same Straiker guardrail and api_version: "2024-09-01"
  2. Startup logs a warning that the api_version is ignored and the route follows the key prefix
  3. The developer sends the same POST https://litellm-domain/v1/chat/completions
  4. Straiker is called on the route matching the key, and the injection comes back as a 400 block

Affected release

Regression since v1.104.0-dev.2 (#41880). Before that, Straiker never read api_version, so a stray value was ignored. This also has to be re-picked onto the 1.101.x backport in #43943

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally
  • My PR passes all required CI/CD checks
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

The integration suite drives a real two-worker proxy with Postgres and Redis and an owned Straiker double, with two new guardrails: a v3 key with api_version: "2024-09-01" and a v1 key with api_version: ""

Before (f553c80)

  1. uv run pytest tests/integration/observability/test_straiker_v3_platform.py -k "stray_api_version or empty_api_version"
  2. Both tests fail with assert 0 == 1 on the detect-call count: the request returned 200 and Straiker was never called, because the guardrail was skipped at startup

After (0c27ce3)

  1. Same command
  2. Both pass: each guardrail calls Straiker on the route its key picks, and the block marker comes back as a 400 with the Straiker block message and no provider call. The full file passes (36 tests) and the unit file passes (139 tests)

Type

🐛 Bug Fix
✅ Test

Caveats (if any)

Low

  • A typo like "V1" with an sk_agt_ key now routes to v3 instead of failing
    • The warning names the ignored value, and v3 is the only route that key works on
  • Constructing StraikerGuardrail directly in Python still rejects unknown values, only config input is lenient

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

REVIEWER MUST KNOW BEFORE APPROVING

  • A Straiker guardrail whose api_version is anything other than v1, v3 or unset (for example "2024-09-01", "", "v2", "V1")
    • Before: the proxy starts without that guardrail, logs "starting WITHOUT this guardrail", and requests pass with no Straiker check
    • After: the guardrail loads, a warning names the ignored value, and the route follows the key (sk_agt_ keys go to v3, other keys to v1)
    • Approved by yucheng-berri in the Devin session that opened this PR ("drive the fix for this", on the plan "log a warning and treat it as unset, so the key prefix picks the route")

Link to Devin session: https://app.devin.ai/sessions/f91d93cb912644a58dcd961679a6d517
Open in Devin Desktop: https://app.devin.ai/desktop/session/f91d93cb912644a58dcd961679a6d517?variant=devin
Requested by: @yucheng-berri


Note

Medium Risk
Changes guardrail startup and API routing for misconfigured Straiker entries; mis-typed versions now follow key prefix instead of failing closed at boot, which restores protection but could surprise admins expecting a hard config error.

Overview
Fixes a regression where Straiker guardrails with a non-v1/v3 api_version (e.g. "2024-09-01" or "") failed config validation at startup and were skipped entirely, so traffic never hit Straiker.

_V3Routing now normalizes unknown api_version values to unset via a Pydantic field_validator, logs a verbose_proxy_logger warning, and leaves explicit v1/v3 unchanged. With api_version unset, routing still follows the API key prefix (sk_agt_ → v3, otherwise v1).

Integration and unit tests cover stray/empty versions, warning behavior, and init_guardrails_v2 registration so enforcement and block paths still run on the correct detect endpoint.

Reviewed by Cursor Bugbot for commit 0c27ce3. Bugbot is set up for automated code reviews on this repo. Configure here.

yucheng-berri and others added 2 commits October 1, 2026 00:53
…ad of skipping the guardrail

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ker api_version test

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor 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

@yucheng-berri

Copy link
Copy Markdown
Contributor

bugbot run

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

@greptileai review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Changes how the guardrail system handles invalid API version inputs.

The PR appears safe to merge.

Summary

The PR treats unknown Straiker api_version values as unset, preserving key-prefix routing instead of skipping the guardrail.

  • Adds unit and integration coverage for stray and empty values.
  • The latest change removes two redundant test comments.

Reviews (3) · Last reviewed commit: "test(guardrails): drop redundant comment..."

greptile-apps[bot]

This comment was marked as resolved.

@codspeed

codspeed Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_straiker_unknown_api_version_unset (0c27ce3) with main (6997223)

Open in CodSpeed

…te from the shared block marker

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

@greptileai review

@yassin-berriai

Copy link
Copy Markdown
Contributor

bugbot run

@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🔍 Devin Review: 1 flag

Not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread tests/integration/observability/test_straiker_v3_platform.py Outdated
… integration tests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

@greptileai review

@yassin-berriai

Copy link
Copy Markdown
Contributor

bugbot run

@yucheng-berri

Copy link
Copy Markdown
Contributor

@greptileai review latest head

@yucheng-berri

Copy link
Copy Markdown
Contributor

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0c27ce3. Configure here.

@yucheng-berri
yucheng-berri merged commit a3a7650 into main Oct 1, 2026
90 of 95 checks passed
@yucheng-berri
yucheng-berri deleted the litellm_straiker_unknown_api_version_unset branch October 1, 2026 01:21
devin-ai-integration Bot added a commit that referenced this pull request Oct 1, 2026
…ad of skipping the guardrail (#43956)

The integration test hunks are dropped because tests/integration/observability/test_straiker_v3_platform.py is not on this line

(cherry picked from commit a3a7650)
yuneng-berri added a commit that referenced this pull request Oct 1, 2026
…-x-89a550

chore(release): backport #41941, #41880, #43956 to stable/1.101.x and cut 1.101.4
jan-sauer-reef added a commit to jan-sauer-reef/litellm that referenced this pull request Oct 1, 2026
…ject_key_prefix

* upstream/main: (62 commits)
  fix(guardrails): scan Responses API input in Azure Prompt Shield (BerriAI#43786)
  feat(lens): investigate sampled traces and retain batch results (BerriAI#43942)
  fix(proxy): restore pre-config-wins handling of pass-through endpoints (BerriAI#43962)
  fix(cost-map): raise baseten DeepSeek-V4.1-Flash max output to 262144 (BerriAI#43916)
  chore(cost-map): add deprecation date for anthropic claude-sonnet-4-5 (BerriAI#43898)
  chore(cost-map): add fireworks inkling priority prices from the prices api (BerriAI#43949)
  feat(guardrails): honor litellm_params.timeout in every HTTP guardrail (BerriAI#43134)
  test(e2e): typed per-test metadata for the e2e suite (BerriAI#42044)
  fix(caching): write the response-cache SET to Redis at once instead of on the post-call batch (BerriAI#43973)
  feat(ui): filter tags by name and description on the Tag Management page (BerriAI#42949)
  feat(providers): add Cortecs as an OpenAI-compatible provider (BerriAI#43872)
  feat(e2e): record each e2e test's steps, starting with ProxyClient (BerriAI#42393)
  test(ci): repair stale tests and move retired OpenAI text-completion fixtures (BerriAI#43958)
  feat(proxy): record in spend logs whether a request used a client-forwarded Anthropic OAuth token (BerriAI#43063)
  fix(azure_storage): keep the DataLakeServiceClient alive until its TTL elapses (BerriAI#43082)
  chore(deps): bump gitpython and tornado, extend diskcache osv ignore to Nov 1 (BerriAI#43961)
  fix(guardrails): treat an unknown straiker api_version as unset instead of skipping the guardrail (BerriAI#43956)
  fix(azure_storage): name Data Lake objects without base64 padding or slashes (BerriAI#43914)
  fix(grayswan): send request conversation and tool calls to post-call monitor (BerriAI#43770)
  chore(cost-map): sync openrouter prices from the models API (BerriAI#43950)
  ...
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