Skip to content

feat: support per-request enable_json_schema_validation for thread safety - #21233

Merged
Chesars merged 3 commits into
BerriAI:litellm_oss_staging_03_03_2026from
Chesars:feat/per-request-json-schema-validation
Mar 3, 2026
Merged

Chesars merged 3 commits into
BerriAI:litellm_oss_staging_03_03_2026from
Chesars:feat/per-request-json-schema-validation

Conversation

@Chesars

@Chesars Chesars commented Feb 15, 2026 •

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes thread-safety issue with litellm.enable_json_schema_validation global flag in concurrent environments (FastAPI, multi-threaded services).

Pre-Submission checklist

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem

Type

🆕 New Feature

Changes

Allow passing enable_json_schema_validation as a per-request parameter to completion() and acompletion(), instead of only relying on the global litellm.enable_json_schema_validation flag.

The global flag isn't thread-safe. In a FastAPI service with concurrent users, one request can change the flag while another is mid-execution:

# Thread A sets it to True
litellm.enable_json_schema_validation = True
# Thread B sets it to False  
litellm.enable_json_schema_validation = False
# Thread A calls completion() — gets False instead of True

Solution: Pass the flag dynamically per-request:

# Thread-safe: each request controls its own validation
completion(..., enable_json_schema_validation=True)
completion(..., enable_json_schema_validation=False)

Priority: per-request value > global value. If not passed, falls back to the global (fully backward compatible).

Files changed:

  • litellm/main.py — added enable_json_schema_validation param to completion() and acompletion()
  • litellm/types/utils.py — registered in all_litellm_params so it doesn't leak to provider APIs
  • litellm/utils.py — post_call_processing() checks per-request value first, falls back to global
  • tests/litellm/litellm_core_utils/test_json_schema_validation.py — 6 tests covering the full matrix

…fety

Allow passing enable_json_schema_validation as a parameter to completion()
and acompletion() instead of only relying on the global
litellm.enable_json_schema_validation flag. The per-request value takes
priority when provided; otherwise falls back to the global (backward
compatible). This makes JSON schema validation safe for concurrent usage
in FastAPI and other multi-threaded environments.
@vercel

vercel Bot commented Feb 15, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Mar 3, 2026 5:55pm

Request Review

@greptile-apps

greptile-apps Bot commented Feb 15, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds per-request enable_json_schema_validation support to completion() and acompletion(), solving a thread-safety issue where concurrent requests sharing the global litellm.enable_json_schema_validation flag could interfere with each other.

  • Adds enable_json_schema_validation: Optional[bool] = None parameter to completion() and acompletion() in litellm/main.py
  • Updates post_call_processing() in litellm/utils.py to check the per-request value first, falling back to the global flag (fully backward-compatible)
  • Registers the param in all_litellm_params to prevent it from leaking to provider APIs
  • Includes 6 mock-only tests covering the full matrix of global/per-request flag combinations

Confidence Score: 5/5

  • This PR is safe to merge — it's a clean, backward-compatible addition with no risk of breaking existing behavior.
  • The changes are minimal and well-scoped: a new optional parameter with None default that falls back to the existing global flag. The param is properly registered in all_litellm_params to prevent leaking. Tests cover all flag combinations without making real network calls. No backwards-incompatible changes.
  • No files require special attention.

Important Files Changed

Filename Overview
litellm/main.py Adds enable_json_schema_validation as an optional parameter to both completion() and acompletion(), and forwards it through completion_kwargs and the MCP handler call. Clean, minimal changes.
litellm/types/utils.py Registers enable_json_schema_validation in all_litellm_params to prevent the parameter from leaking to provider APIs. Single-line addition.
litellm/utils.py Updates post_call_processing to check per-request enable_json_schema_validation from optional_params before falling back to the global flag. Logic is correct and backward-compatible.
tests/litellm/litellm_core_utils/test_json_schema_validation.py Comprehensive test suite covering all 4 combinations of global/per-request flags, valid response pass-through, and param registration. No real network calls—uses mock data directly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["completion() / acompletion()"] -->|"enable_json_schema_validation param"| B["@client decorator wrapper"]
    B --> C["post_call_processing()"]
    C --> D{"Per-request flag\nin optional_params?"}
    D -->|Yes| E["Use per-request value"]
    D -->|No / None| F["Use global\nlitellm.enable_json_schema_validation"]
    E --> G{"Flag is True?"}
    F --> G
    G -->|Yes| H["Validate response\nagainst JSON schema"]
    G -->|No| I["Skip validation"]
    H -->|Invalid| J["Raise JSONSchemaValidationError"]
    H -->|Valid| K["Continue normally"]
Loading

Last reviewed commit: 909e3ce

@greptile-apps greptile-apps 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.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps

greptile-apps Bot commented Feb 15, 2026

Copy link
Copy Markdown
Contributor
Additional Comments (1)

litellm/main.py
Missing enable_json_schema_validation in MCP delegation

When completion() delegates to acompletion_with_mcp for MCP tool handling, the new enable_json_schema_validation parameter is not forwarded. Since it's a named parameter in the completion() signature, it is NOT included in **kwargs at line 1173 — it's a separate local variable that gets silently dropped.

This means per-request JSON schema validation will not work when MCP tools are present. Add enable_json_schema_validation=enable_json_schema_validation, before **kwargs:

                shared_session=shared_session,
                enable_json_schema_validation=enable_json_schema_validation,
                **kwargs,

The parameter was declared in completion() signature but not passed
to acompletion_with_mcp, causing per-request JSON schema validation
to silently fall back to the global default when MCP tools are present.
Comment thread tests/litellm/litellm_core_utils/test_json_schema_validation.py Outdated
@Chesars
Chesars changed the base branch from main to litellm_oss_staging_03_03_2026 March 3, 2026 17:52
@Chesars
Chesars merged commit d384f7c into BerriAI:litellm_oss_staging_03_03_2026 Mar 3, 2026
4 of 5 checks passed
@Chesars
Chesars deleted the feat/per-request-json-schema-validation branch March 3, 2026 18:30
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…chema-validation

feat: support per-request enable_json_schema_validation for thread safety

This branch was successfully deployed

1 active deployment
Preview — 909e3ce6 Deployed Mar 3, 2026 by vercel[bot]
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.

1 participant