---
title: "Never return null · Agent Wranglers"
url: https://agentwranglers.se/playbook/architecture/errors-and-nulls/never-return-null
updated: 2026-10-20
licence: "All rights reserved"
---

# Never return null

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Errors and nulls](https://agentwranglers.se/playbook/architecture/errors-and-nulls)
- Rule: Collections return empty, services use a Null Object, and lookups return one consistent "absent" value. A caller should never crash because it forgot a check.
- How: Return `[]` for "no results". Use a Null Object, such as a mailer that sends nothing, when a default behaviour makes sense. A lookup that may find nothing returns the language's one absent value, such as `undefined`, `Optional` or `None`. Convert it to an error or a default where the result is used, never deeper.
- Check: Strict null checks make every absent return visible, such as `strictNullChecks` in TypeScript, PHPStan level 8 or higher, or mypy `--strict`. Reviewers fail collections and services that can return null. A test calls each finder with no matches and expects an empty result.

Example:

```ts
// Bad: every caller must remember the null check
function ordersFor(customerId: string): Order[] | null {
  return db.has(customerId) ? db.get(customerId) : null;
}

// Good: no results is an empty list
function ordersFor(customerId: CustomerId): Order[] {
  return db.get(customerId) ?? [];
}

// Good: a lookup has one absent value, handled where it is used
function findCustomer(id: CustomerId): Customer | undefined {
  return customers.get(id);
}
const customer = findCustomer(id);
if (!customer) throw new CustomerNotFound(id);
```

```python
# Python: an empty list for no results, and None as the one absent value for a lookup
def orders_for(customer_id: str) -> list[Order]:
    return orders.get(customer_id, [])

def find_customer(customer_id: str) -> Customer | None:
    return customers.get(customer_id)
```

```java
// Java: Optional makes the absent case part of the type
Optional<Customer> findCustomer(CustomerId id) {
    return Optional.ofNullable(customers.get(id));
}
Customer customer = findCustomer(id).orElseThrow(() -> new CustomerNotFound(id));
```

**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/never-return-null`.

- Previous: [Use typed domain exceptions](https://agentwranglers.se/playbook/architecture/errors-and-nulls/domain-exceptions)
- Next: [Never pass null into a function](https://agentwranglers.se/playbook/architecture/errors-and-nulls/never-pass-null)
- [Errors and nulls](https://agentwranglers.se/playbook/architecture/errors-and-nulls)
