## TL;DR

The timestamp strategy needs an updated_at column on the source and it is not there. Either add the column upstream, point updated_at to a column that does exist, or switch the snapshot to check_cols strategy which needs no timestamp.

## Error

```text
dbt snapshot failed: updated_at column missing
```

## Steps

1. Open the snapshot definition and note the strategy and the updated_at column name it expects.
   Expected: You see strategy: timestamp and updated_at: some_column.

2. Check the source table: does some_column exist? Query the information schema or select the column directly.
   Expected: You confirm the column is missing, misnamed, or null for all rows.

3. Fix it: rename updated_at to a real timestamp column, or change strategy to check_cols with check_cols: all (or a column list).
   Expected: The snapshot config references only columns that exist.

4. Run dbt snapshot --select the_snapshot.
   Expected: Snapshot builds and records history rows.

## When to use

- dbt snapshot fails saying the updated_at column is missing
- the source table never had a reliable updated_at
- after a source schema change renamed the timestamp column

## When not to use

- snapshot fails on the unique key (that is a key problem, different fix)
- the target database does not exist (that is a schema problem)
- you want check_cols behavior but configured timestamp

## Tool compatibility

- dbt snapshots; timestamp vs check_cols strategies
- information_schema to verify source columns
- dbt snapshot --select runs one snapshot

## Variant phrasings

### updated_at exists but is all null
The timestamp strategy cannot order nulls. Switch to check_cols, or fix the source to populate the column.

### updated_at missing after a source migration
The new source names it differently. Update the snapshot config; do not rename the source column to suit dbt.

## Why it happens

The timestamp strategy detects changes by comparing each row's updated_at to the last snapshot run. No column, no comparison. Sources without reliable timestamps were never a fit for this strategy; check_cols compares actual values instead.

## Edge cases

- check_cols: all on wide tables is expensive; list the meaningful columns instead.
- Changing strategies on an existing snapshot changes history semantics; backfill or accept the seam, and document it.

## Provenance

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