Skip to content

JSON Output

The json format emits the full lineage + impact result as a single machine-readable object. It is the surface designed for programmatic consumers — CI scripts and AI agents that need to reason about a change rather than read a report.

dbt-col-lineage --select stg_accounts.account_id+ \
  --manifest target/manifest.json \
  --catalog target/catalog.json \
  --format json

The selector direction controls which side is populated: +model.col fills upstream, model.col+ fills downstream, and model.col fills both.

Shape

{
  "model": "stg_accounts",
  "column": "account_id",
  "data_type": "INTEGER",
  "description": "Unique identifier for the account, cast to integer from the raw source id.",
  "model_description": "Staging model for account data.",
  "downstream": {
    "models": {
      "accounts_snapshot": {
        "account_id": {
          "source_columns": ["stg_accounts.account_id"],
          "transformation_type": "direct",
          "sql_expression": null,
          "description": null
        }
      }
    },
    "sources": [],
    "direct_refs": [],
    "exposures": [
      {
        "name": "transactions_dashboard",
        "type": "dashboard",
        "url": "https://example.com/reports/transactions",
        "description": "Main dashboard showing transaction data and metrics.",
        "depends_on_models": ["transactions"]
      }
    ]
  },
  "impact": {
    "summary": {
      "affected_models": 4,
      "affected_columns": 4,
      "affected_exposures": 2,
      "critical_count": 0,
      "low_impact_count": 3,
      "filter_count": 0
    },
    "affected_models": [
      {
        "name": "accounts_snapshot",
        "resource_type": "snapshot",
        "schema": "main",
        "database": "main",
        "description": "Snapshot of account data using SCD Type 2."
      }
    ],
    "affected_columns": [
      {
        "model": "int_transactions_enriched",
        "column": "amount_category",
        "transformation_type": "derived",
        "sql_expression": "CASE WHEN amount > 100 THEN 'high' ELSE 'low' END",
        "severity": "critical",
        "data_type": "TEXT",
        "description": "Bucketed amount label."
      }
    ],
    "affected_exposures": [ /* same shape as downstream.exposures[] */ ],
    "confidence": {
      "reachable_models": 6,
      "resolved_models": 6,
      "unanalyzable_models": 0,
      "no_column_info": 0,
      "parse_failed": 0,
      "no_column_info_models": [],
      "parse_failed_models": [],
      "level": "full"
    }
  },
  "coverage": {
    "models_in_manifest": 13,
    "models_in_catalog": 13,
    "parsed_ok": 13,
    "parse_failed": 0,
    "skipped_no_sql": 0,
    "not_in_catalog_count": 0,
    "failed_models": [],
    "skipped_models": [],
    "complete": true
  }
}

upstream (when requested with +model.col) has the same structure as downstream.

Top-level fields

Field Type Meaning
model string The selected model.
column string The selected column.
data_type string | null Column type, from catalog.json when available.
description string | null dbt-authored description of the selected column (from the manifest).
model_description string | null dbt-authored description of the selected model.
upstream / downstream object Lineage in the requested direction (see below).
impact object The blast-radius analysis (see below).
coverage object How complete the analysis is (see below).

downstream / upstream

Field Type Meaning
models object model → column → {source_columns[], transformation_type, sql_expression, description}. transformation_type is direct (pass-through), renamed, or derived (computed). sql_expression is set for derived columns.
sources array Referenced dbt sources.
direct_refs array Direct column references.
exposures array {name, type, url, description, depends_on_models[]} — business-facing consumers (dashboards, apps).

impact

impact.summary

Field Meaning
affected_models Count of downstream models whose output is affected.
affected_columns Count of downstream columns affected.
affected_exposures Count of affected business-facing exposures.
critical_count Affected columns that recompute derived logic (the highest-risk band).
low_impact_count Affected columns that are plain pass-through references.
filter_count Dependents affected via a predicate (filter/join), not a projected column.

impact.affected_columns[]

Field Meaning
model, column The affected downstream column.
severity critical (recomputes derived logic), low_impact (pass-through reference), or filter (affected via a predicate).
transformation_type direct, renamed, or derived.
sql_expression The expression when the column is derived (null otherwise).
data_type Column type when known.
description dbt-authored description when present.

affected_models[] carries {name, resource_type, schema, database, description}; affected_exposures[] matches downstream.exposures[].

coverage and impact.confidence — is the answer complete?

Static analysis is only as complete as the artifacts allow. These blocks tell a consumer when the result is a lower bound so an agent doesn't treat a partial answer as "nothing breaks."

Field Meaning
coverage.models_in_manifest / models_in_catalog Universe sizes. A catalog smaller than the manifest is expected (the catalog reflects warehouse-built state).
coverage.parsed_ok / parse_failed How many models' SQL parsed. failed_models[] lists the ones that didn't.
coverage.not_in_catalog_count Reachable models with no catalog entry (column types unknown).
coverage.complete true only when every reachable model was analyzable.
impact.confidence.level full or partial — the headline confidence for this impact result.
impact.confidence.parse_failed_models / no_column_info_models The specific models that limited the analysis.

Trust the coverage before the impact

When coverage.complete is false (or confidence.level is partial), the impact counts are a lower bound — there may be more downstream breakage in the models that couldn't be analyzed. Rebuild them (dbt run --select <model>+ --empty && dbt docs generate) and re-run for a complete answer.

Feeding this to an AI agent

The bundled Claude Code skills under skills/dbt-lineage/ are the reference implementation: they wrap these commands and consume this JSON to answer "what breaks if I change this column?" directly in an agent loop.