This rule raises an issue when a validation model class has fields typed to accept instances of dataclasses, but does not explicitly configure the framework’s revalidation behavior for those instances.

In Pydantic specifically, this refers to BaseModel classes with fields typed as standard library or Pydantic dataclasses.

Why is this an issue?

Validation frameworks do not revalidate pre-existing data structure instances by default. When an already-instantiated object is passed as a field value, the framework skips validation and accepts it as-is — even if the object was constructed with invalid data. Because lightweight data structures such as dataclasses perform no runtime type checking themselves, invalid field values can silently enter a validated model without raising any error.

Exceptions

This rule does not raise an issue when revalidate_instances is explicitly set, regardless of the value. An explicit 'never' signals that the developer has made a conscious choice to skip revalidation — for example, when dataclass instances are always constructed from trusted, pre-validated data.

In Pydantic, for example, constructing User(name=['not', 'a', 'string']) succeeds because dataclasses.dataclass does not check types at runtime. Passing that instance to a BaseModel field typed as User raises no ValidationError — the list is stored silently in place of the expected string.

What is the potential impact?

Without proper revalidation, your application may process invalid data that should have been rejected. This can lead to:

How to fix it

There are two ways to address this issue.

Option 1: Set revalidate_instances explicitly

Explicitly set revalidate_instances on the BaseModel that holds the dataclass field. This can be done with ConfigDict or as a class keyword argument.

Choose the value that matches your intent:

Note that enabling revalidate_instances can have a runtime cost, particularly when a model with many nested Pydantic fields holds a single dataclass field, since all nested models are also revalidated recursively.

Option 2: Replace the dataclass with a Pydantic model

Convert the dataclass to a BaseModel (or a Pydantic dataclass). Pydantic models are validated at construction time, so no extra revalidation configuration is needed.

Code examples

Noncompliant code example

import dataclasses
from pydantic import BaseModel

@dataclasses.dataclass
class User:
    name: str

class Foo(BaseModel):  # Noncompliant
    user: User

Compliant solution

import dataclasses
from pydantic import BaseModel, ConfigDict

@dataclasses.dataclass
class User:
    name: str

class Foo(BaseModel, revalidate_instances='always'):  # always revalidate
    user: User

class Bar(BaseModel):  # ConfigDict syntax
    model_config = ConfigDict(revalidate_instances='always')
    user: User

class Baz(BaseModel, revalidate_instances='never'):  # explicitly opt out
    user: User

Noncompliant code example

import dataclasses
from pydantic import BaseModel

@dataclasses.dataclass
class Address:
    street: str

class Order(BaseModel):  # Noncompliant
    shipping_address: Address

Compliant solution

from pydantic import BaseModel

class Address(BaseModel):  # Pydantic model — validated at construction time
    street: str

class Order(BaseModel):
    shipping_address: Address

Resources

Documentation