## TL;DR

Something returned None and the code indexed into it like result['key']. Find the call that can return None (often adapter.get_relation or a macro returning nothing), guard it with an if check, and only subscript after you know it is real.

## Error

```text
dbt run error: NoneType object is not subscriptable
```

## Steps

1. Get the traceback with --debug. It names the file and line doing the subscription, e.g. result['rows'] where result is None.
   Expected: You have the exact line and the variable that is None.

2. Trace the variable's source: usually a function or macro that returns None on a miss, like adapter.get_relation for a nonexistent relation, or a python model helper with an early return.
   Expected: You can name the call that produced None.

3. Guard it: if result is None: handle the miss (raise a clear error, or default), and only subscript inside the else branch. In jinja macros, check {% if result %} first.
   Expected: The None path is handled explicitly instead of crashing.

4. Re-run the model or macro, plus any other callers of the same helper.
   Expected: Clean run; the miss case now produces a clear message or a default.

## When to use

- dbt fails with NoneType object is not subscriptable in a python model or macro
- after adding a lookup (get_relation, var dict access) that can miss
- a macro that returns nothing on some code path

## When not to use

- dict object has no attribute (the object exists, a key is missing, different fix)
- warehouse SQL errors with no python traceback
- the error is in dbt core internals with no project code in the trace (then check versions)

## Tool compatibility

- dbt python models (1.3+) and jinja macros both hit this
- --debug is required to see the project-code line in the traceback
- dbt Cloud run logs include the traceback too

## Variant phrasings

### NoneType object is not subscriptable in a snapshot
Usually adapter.get_relation returning None for the target table on first run. Guard the None case as table-not-yet-created.

### error inside dbt-utils macro
Check your arguments first; dbt-utils macros return None-ish results when given an empty relation list. Then pin the package version.

## Why it happens

dbt helpers return None to signal not found, and jinja/python happily pass that along until something subscripts it. The crash site is rarely the bug site; the bug is the unhandled miss one call up the stack.

## Edge cases

- In jinja, {% set x = none_value['k'] %} fails the same way; jinja None subscripting raises like python.
- If the None comes from dbt internals after an upgrade, check the adapter version matrix before rewriting project code.

## Provenance

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