The Fix
pip install pydantic==2.9.0
Based on closed pydantic/pydantic issue #10111 · PR/commit linked
@@ -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)):
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"}
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
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
- GitHub issue: #10111
- Fix PR: https://github.com/pydantic/pydantic/pull/10210
- First fixed release: 2.9.0
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.85
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.44
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“@aditkumar72, good question”
“We'd welcome support for this. PRs welcome!”
“Hi @sydney-runkle, Could you please assign this to me ?”
“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”
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
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 Message
-------------
json-schema for `NotMultipleOf(2)` would look like `"not": {"multipleOf": 2}`
- [ ] [Compatibility between releases](https://docs.pydantic.dev/changelog/)
Minimal Reproduction
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
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.
When NOT to Use This Fix
- Do not use this fix if you require backward compatibility with Pydantic 1.
Verify Fix
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
| Version | Status |
|---|---|
| 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.