Unsupported Field Override Error
Description
This error is thrown when a strawberry.pydantic type overrides a field with a
resolver, inherited from a base model or an interface, with something that isnβt
a field, like a method without @strawberry.pydantic.field . For example the
following code will throw this error:
import pydanticimport strawberry
@strawberry.pydantic.typeclass User(pydantic.BaseModel): name: str
@strawberry.pydantic.field def greeting(self) -> str: return f"Hi {self.name}"
@strawberry.pydantic.typeclass Admin(User): def greeting(self) -> str: return f"Welcome back, {self.name}" This happens because the method replaces the inherited one, so Admin wouldnβt
have a greeting field anymore, even though it most likely should.
The same error is thrown when:
- a field with a resolver has the name of a field of the model, as Pydantic would use the method as the default value of the field, and never call the resolver.
- a method overrides an inherited computed field, as Pydantic would keep the computed field, and use the method itself as its value.
Fields of the model and computed fields can still override inherited fields with
a resolver, unless computed fields are left out with include_computed=False ,
and properties can override computed fields.
How to fix this error
To change the resolver of an inherited field, decorate the method with
@strawberry.pydantic.field :
import pydanticimport strawberry
@strawberry.pydantic.typeclass User(pydantic.BaseModel): name: str
@strawberry.pydantic.field def greeting(self) -> str: return f"Hi {self.name}"
@strawberry.pydantic.typeclass Admin(User): @strawberry.pydantic.field def greeting(self) -> str: return f"Welcome back, {self.name}" To change a computed field, make the method a computed field too, with
@pydantic.computed_field and @property , or a field with a resolver, which
can take arguments, with @strawberry.pydantic.field .
If the method isnβt meant to be part of the GraphQL type, rename it, so that the inherited field is kept. A resolver with the name of a field of the model needs another name, unless the model field is removed.
To have a field with a resolver only on some of the types that share a base model, move it to a base model that only those types extend:
import pydanticimport strawberry
class UserBase(pydantic.BaseModel): name: str
class GreeterBase(UserBase): @strawberry.pydantic.field def greeting(self) -> str: return f"Hi {self.name}"
@strawberry.pydantic.typeclass User(GreeterBase): pass
@strawberry.pydantic.typeclass Admin(UserBase): pass