In Pydantic v2 @validator became @field_validator and the signature changed. The decorated function must be a classmethod, receives the value, and gets sibling values through a second ValidationInfo parameter as info.data rather than through the old values argument.
The part that breaks logic rather than syntax is that info.data contains only the fields that have already been validated, in field definition order, and it omits any field whose own validation failed. A cross-field check written against a field declared later in the class silently sees a missing key, and the validator appears to do nothing.
For anything comparing two fields, use @model_validator(mode="after") instead. It runs once on the constructed model, has every field available as attributes, and returns self. mode="before" receives the raw input dict before any coercion, which is the right place for renaming or restructuring incoming data. The bump-pydantic tool performs the mechanical rename but cannot fix the ordering assumption, so review every cross-field validator by hand.