## TL;DR

A macro treated a list like a dictionary. Find the variable, check its real shape (often the result of run_query, a var, or modules output is a list of rows), and index or loop it instead of calling .get. Printing the variable with log() during compile shows the true structure fast.

```text
dbt.exceptions.CompilationError: 'list' object has no attribute 'get'
```

## Use this when

- dbt compile or run fails with CompilationError list object has no attribute get
- the failing code is a macro iterating config, vars, or a query result
- the error appeared after changing a var from a mapping to a list, or after a package upgrade changed a return type

## Not for this skill when

- the object really should be a dict, fix the YAML var definition shape instead of the macro
- the error is dict has no attribute for a different method, inspect that call instead
- you are writing plain Python outside dbt, where this Jinja context does not apply

## Steps

1. Locate the .get call: run dbt compile with --debug, find the macro and line in the traceback, and open that macro.
   Verify: you know the exact expression calling .get and the variable it is called on.

2. Add a temporary log call just above it, for example log(var_name and var_name[0] or var_name, info=true), then compile one model to see whether the value is a list and what its first element looks like. Remove the debug log afterwards.
   Verify: the logged output shows the real type and shape of the variable.

3. Fix the access pattern: if it is a list of dicts, loop over items and call .get on each item, or index the intended element first. If it came from run_query, use the table rows or columns API instead of dict access.
   Verify: the macro accesses elements with the correct type at each step.

4. Recompile the affected models and run one end to end.
   Verify: dbt compile and dbt run succeed with no attribute error and the rendered SQL is unchanged apart from the fix.

## Variant phrasings

### var defined as a list in dbt_project.yml
Vars preserve YAML types. A var written with dash lines is a list even if the macro author expected a mapping; align the macro or the var, and document the shape.

### results from a hook
The results object in on-run-end is a list of result objects, not a dict keyed by model. Loop it and filter by node name.

Compatibility: dbt-core 1.x Jinja environment (Jinja2) for macros, models, and hooks; YAML vars keep their YAML types on all adapters.

## Why it happens

Jinja in dbt is dynamically typed: nothing stops a macro from calling a dict method on a list until render time. Upstream data shapes (vars, query results, package return values) decide the real type, and when one of them is a list of records rather than a single record, .get fails immediately with this CompilationError.

## Edge cases / pitfalls

- An empty list hides the bug until data exists; test the macro with empty and multi-row inputs.
- Chained .get calls fail on the first wrong type, so fixing one call may reveal the next; recompile after each fix.
- Do not convert with a blind dict() call; a list of pairs and a list of dicts need different handling.

## Provenance

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