v0.279.0 Breaking Changes
This release changes the strawberry.Maybe
type definition to provide a more
consistent and intuitive API for handling optional fields.
What Changed
The Maybe
type definition has been changed from:
Maybe: TypeAlias = Union[Some[Union[T, None]], None]
to:
Maybe: TypeAlias = Union[Some[T], None]
Impact on Your Code
Type Annotations
If you were using Maybe[T]
and expecting to handle explicit null
values, you
now need to explicitly declare this with Maybe[T | None]
:
# Before (0.278.0 and earlier)field: strawberry.Maybe[str] # Could handle Some(None)
# After (0.279.0+)field: strawberry.Maybe[str] # Only handles Some("value") or None (absent)field: strawberry.Maybe[str | None] # Handles Some("value"), Some(None), or None
Runtime Behavior
The runtime behavior changes to provide more consistent field checking:
-
Maybe[str]
now represents “field present with non-null value” or “field absent” -
Maybe[str | None]
represents “field present with value”, “field present but null”, or “field absent”
This means Maybe[str]
can no longer receive explicit null
values - they will
cause a validation error.
Consistent Field Checking
This change provides a single, consistent way to check if a field was provided, regardless of whether the field allows null values:
@strawberry.inputclass UpdateUserInput: # Can be provided with a value or not provided at all name: strawberry.Maybe[str]
# Can be provided with a value, provided as null, or not provided at all phone: strawberry.Maybe[str | None]
@strawberry.mutationdef update_user(input: UpdateUserInput) -> User: # Same checking pattern for both fields if input.name is not None: # Field was provided user.name = input.name.value # Type checker knows this is str
if input.phone is not None: # Field was provided user.phone = input.phone.value # Type checker knows this is str | None
The key benefit is that if field is not None
now consistently means “field was
provided” for all Maybe fields.
Migration
Automatic Migration
Strawberry provides a codemod to automatically update your code:
strawberry upgrade maybe-optional
The codemod will automatically convert Maybe[T]
to Maybe[T | None]
to
maintain the previous behavior.
Manual Migration
Review your Maybe
usage and decide whether you need the union type:
# If you only need "present" vs "absent" (most common case)field: strawberry.Maybe[str]
# If you need "present with value", "present but null", and "absent"field: strawberry.Maybe[str | None]
Why This Change?
After extensive discussion, we decided that changing Maybe
to Some[T] | None
(instead of Some[T | None] | None
) provides the best developer experience
because:
-
Consistent field checking: You can always use
if field is not None:
to check if a field was provided, regardless of whether the field allows null values -
Preserves existing behavior: You can still get the previous behavior by using
Maybe[T | None]
when you need to handle explicit nulls -
Better type safety:
Maybe[str]
now properly indicates that the field cannot be null, whileMaybe[str | None]
explicitly allows nulls -
Cleaner API: There’s now “one true way” to check if a field was provided, making the API more intuitive
The new approach provides both simplicity for common cases and flexibility for complex scenarios where null handling is needed.
Need Help?
- See the Maybe documentation for comprehensive usage examples
- Check the migration guide for detailed migration instructions
- If you encounter issues, please report them on GitHub