Jump to solution
Verify

The Fix

pip install pydantic==2.9.0

Based on closed pydantic/pydantic issue #10111 · PR/commit linked

Jump to Verify Open PR/Commit
@@ -299,17 +299,25 @@ def _apply_constraint_with_incompatibility_info( ) continue - elif isinstance(annotation, at.Predicate): - predicate_name = f'{annotation.func.__qualname__} ' if hasattr(annotation.func, '__qualname__') else '' + elif isinstance(annotation, (at.Predicate, at.Not)):
repro.py
from functools import partial from typing_extensions import Annotated import annotated_types from pydantic import AfterValidator, TypeAdapter, WithJsonSchema def validate_not_multiple_of(x: int, y: int) -> int: if x % y == 0: raise ValueError(f"value must not be multiple of {y}") return x PositiveOddInt = Annotated[ int, annotated_types.Gt(0), AfterValidator(partial(validate_not_multiple_of, y=2)), WithJsonSchema({"type": "positive_odd_int"}), ] ta = TypeAdapter(PositiveOddInt) assert ta.validate_python(3) == 3 assert ta.dump_json(3) == b"3" assert ta.json_schema() == {"type": "positive_odd_int"}
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Upgrade to fixed release\npip install pydantic==2.9.0\nWhen NOT to use: Do not use this fix if you require backward compatibility with Pydantic 1.\n\n

Why This Fix Works in Production

  • Trigger: json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}`
  • Mechanism: Adds support for annotated_types.Not, allowing for more flexible type definitions in Pydantic.
  • Why the fix works: Adds support for annotated_types.Not, allowing for more flexible type definitions in Pydantic. (first fixed release: 2.9.0).

Why This Breaks in Prod

  • Production symptom (often without a traceback): json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}`

Proof / Evidence

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“@aditkumar72, good question”
@sydney-runkle · 2024-08-20 · source
“We'd welcome support for this. PRs welcome!”
@sydney-runkle · 2024-08-12 · source
“Hi @sydney-runkle, Could you please assign this to me ?”
@aditkumar72 · 2024-08-16 · source
“Hi @georgievgeorgi @sydney-runkle Can we use something like this ? If I am not mistaken, supporting annotated_types.Not would require changes in pydantic-core”
@aditkumar72 · 2024-08-17 · source

Failure Signature (Search String)

  • json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}`
  • - [ ] [Compatibility between releases](https://docs.pydantic.dev/changelog/)
Copy-friendly signature
signature.txt
Failure Signature ----------------- json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}` - [ ] [Compatibility between releases](https://docs.pydantic.dev/changelog/)

Error Message

Signature-only (no traceback captured)
error.txt
Error Message ------------- json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}` - [ ] [Compatibility between releases](https://docs.pydantic.dev/changelog/)

Minimal Reproduction

repro.py
from functools import partial from typing_extensions import Annotated import annotated_types from pydantic import AfterValidator, TypeAdapter, WithJsonSchema def validate_not_multiple_of(x: int, y: int) -> int: if x % y == 0: raise ValueError(f"value must not be multiple of {y}") return x PositiveOddInt = Annotated[ int, annotated_types.Gt(0), AfterValidator(partial(validate_not_multiple_of, y=2)), WithJsonSchema({"type": "positive_odd_int"}), ] ta = TypeAdapter(PositiveOddInt) assert ta.validate_python(3) == 3 assert ta.dump_json(3) == b"3" assert ta.json_schema() == {"type": "positive_odd_int"}

Environment

  • Pydantic: 1

What Broke

Users could not define types like PositiveOddInt, leading to validation issues.

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

pip install pydantic==2.9.0

When NOT to use: Do not use this fix if you require backward compatibility with Pydantic 1.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Fix reference: https://github.com/pydantic/pydantic/pull/10210

First fixed release: 2.9.0

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not use this fix if you require backward compatibility with Pydantic 1.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Add a CI check that diffs key outputs after upgrades (OpenAPI schema snapshots, JSON payload shapes, CLI output).
  • Upgrade behind a canary and run integration tests against the canary before 100% rollout.

Version Compatibility Table

VersionStatus
2.9.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.