Errors and nulls Required
Make fields required unless absence is real
Every constructor argument and data object field is required and non-nullable, unless "not there" is a real state of the business.
How to do it
Ask for each optional field what it means when it is empty. If it is always set in practice, make it required. If absence has a meaning, such as "not shipped yet", name that state with its own type or an optional field. Build objects fully in the constructor, never half-filled with setters.
Example
// Bad: everything is nullable, so nothing can be trusted
final class Shipment
{
public function __construct(
public ?string $orderId = null,
public ?string $address = null,
public ?DateTimeImmutable $shippedAt = null,
) {}
}
// Good: only shippedAt may be missing, because "not shipped yet" is real
final class Shipment
{
public function __construct(
public readonly OrderId $orderId,
public readonly Address $address,
public readonly ?DateTimeImmutable $shippedAt,
) {}
}
How to check
A type checker rejects missing fields, such as TypeScript strict, PHPStan level max or mypy --strict. Reviewers fail any nullable field that no code path ever leaves empty.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers architecture playbook: https://agentwranglers.se/playbook/architecture/errors-and-nulls/required-fields.