## TL;DR

`accepted_values` treats null as a failure unless you tell it otherwise. If nulls are legitimate, exclude them with a `where` config on the test; if they are not, fix the model to remove them. Then rerun the test.

## Error

```text
dbt test accepted_values failed on nulls
```

## Steps

1. Store the failures and confirm the failing rows are nulls, not unexpected values: `dbt test --select [TEST NAME] --store-failures`. Expected: the failures table shows nulls.
2. Decide the business rule: are nulls allowed in this column? Expected: a yes-or-no answer from the data owner or the pipeline contract.
3. If nulls are allowed, add a `where` filter to the test config to exclude them:
```yaml
tests:
  - accepted_values:
      values: ['a', 'b']
      config:
        where: "status is not null"
```
Expected: the test now ignores null rows.
4. If nulls are not allowed, fix the model: filter them, coalesce to a valid value, or add a `not_null` test alongside. Expected: the model no longer emits nulls.
5. Rerun the test. Expected: it passes.

## When to use

- An `accepted_values` test fails and the failing rows are nulls.
- You just added the test to a column that historically contains nulls.

## When not to use

- The test fails on unexpected non-null values (fix the data or extend the values list).
- Nulls should never occur (add a `not_null` test and fix the model).

## Tool compatibility

- dbt Core 1.0 and later, all adapters. `where` test configs are adapter-independent.

## Variant phrasings

### accepted_values fails after a source change introduced nulls

The source contract changed; update the model or the test to match.

### Combining accepted_values with not_null

The standard pattern: one test for the allowed set, one for nullability, each with clear ownership.

## Why it happens

SQL nulls never equal any value, so they never match the accepted list. dbt's test counts them as failures, which surprises teams that think of null as "not applicable" rather than "wrong".

## Edge cases

- Empty strings are not nulls; they fail as unexpected values, not as nulls.
- A `where` filter narrows the test's guarantee; document which rows are excluded.
- Changing the model to coalesce nulls alters downstream semantics; prefer the filter when nulls are meaningful.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_KEYkWovkXf7qBOQrXZlDkg
