## TL;DR

Something called .execute on None, most often a macro or hook that grabbed a connection or statement result that does not exist in that context, or a run_query call made at parse time when no connection is open. Guard data calls with if execute, and fetch connections through the adapter API inside run contexts. The run then either skips the call at parse time or executes on a real cursor.

```text
'NoneType' object has no attribute 'execute' in dbt run
```

## Use this when

- dbt run crashes with NoneType object has no attribute execute
- the traceback points at a macro, on-run-start hook, or a statement call
- the failure happens before any model SQL runs, or only in some commands such as parse or compile

## Not for this skill when

- the warehouse returned an error message, that error is quoted as a Database Error instead
- you see the error in application Python that uses dbt as a library, fix the caller session handling
- the failing attribute is columns or database, those point at relation lookup instead of connection handling

## Steps

1. Re-run with --debug and read the full traceback to find the file and line calling execute, usually inside a macro using run_query, statement, or adapter code.
   Verify: the traceback names the macro or hook and the exact call.

2. Check the context that call runs in: if the macro can be invoked during parsing, wrap the database-touching part in an if execute check so it only runs when dbt is executing, not parsing.
   Verify: the macro body guards its database call behind execute.

3. If the code obtains a connection manually, replace manual handling with the standard pattern: use adapter.get_connection to get a live connection, or call run_query and read its result table instead of touching a cursor directly.
   Verify: the code no longer calls execute on a possibly empty handle.

4. Run dbt run --select on a model that triggers the macro or hook, in both compile and run modes.
   Verify: dbt compile succeeds without touching the warehouse and dbt run completes the model.

## Variant phrasings

### only fails on dbt parse or docs generate
Those commands do not open execution connections the same way. The execute guard fixes it; do not open raw connections at parse time.

### fails inside an on-run-end hook
Hooks run after models, and results available there are limited. Read the results object defensively and skip missing entries instead of executing follow-up SQL blindly.

Compatibility: dbt-core 1.x macros and hooks using run_query, statement blocks, and adapter.get_connection; behavior is adapter specific for raw cursor access.

## Why it happens

dbt renders templates in phases. During parsing there is no live warehouse connection, and several helper objects are None placeholders. Code that assumes a live cursor and calls execute on the placeholder crashes with this attribute error. The fix is phase-aware code, not a warehouse fix.

## Edge cases / pitfalls

- run_query returns an agate table; treating it like a cursor and calling execute on it is a common variant of this bug.
- Caching a connection across models fails when dbt rotates connections per thread; fetch it where you use it.
- Silencing the error with a broad try block hides real warehouse failures; guard on execute and on None, not on all exceptions.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_b6JmQd2nf7nl-4V3JvLJkw
