> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dqlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# FAQ

> Common questions about connecting dbt to Prizm, artifact ingestion, lineage, test results, and troubleshooting.

<script type="application/ld+json">
  {`{
            "@context": "https://schema.org",
            "@type": "TechArticle",
            "headline": "dbt FAQ",
            "description": "Common questions about connecting dbt to Prizm, artifact ingestion, lineage, test results, and troubleshooting.",
            "url": "https://docs.dqlabs.ai/sources/dbt/faq",
            "publisher": {
              "@type": "Organization",
              "name": "DQLabs Inc",
              "logo": "https://media.brand.dev/332adc35-5bc4-4d2b-bf78-256aa4a5e414.svg"
            }
            }`}
</script>

## Connection & Authentication

<AccordionGroup>
  <Accordion title="Which setup mode should I use — dbt Cloud or dbt Core?">
    Use **dbt Cloud** if you run dbt jobs through dbt Cloud's scheduler or CI/CD features. Prizm connects via the dbt Cloud API and can receive run events via webhook, eliminating the need for any pipeline changes.

    Use **dbt Core** if you run dbt locally, in Airflow, in GitHub Actions, Jenkins, or any custom orchestration. Add the `prizm-dbt push-artifacts` command as a step after your dbt commands.

    Both modes produce identical catalog, lineage, and observability output in Prizm. The choice is purely based on how your dbt project is run.
  </Accordion>

  <Accordion title="What credentials does dbt Cloud integration require?">
    | Field             | Description                                                                                                         |
    | :---------------- | :------------------------------------------------------------------------------------------------------------------ |
    | **Account ID**    | Found in your dbt Cloud URL: `cloud.getdbt.com/accounts/<account_id>/`                                              |
    | **Service Token** | Create in dbt Cloud → Account Settings → Service Tokens. Assign Metadata Only permissions.                          |
    | **Access URL**    | Your dbt Cloud region endpoint — US: `https://cloud.getdbt.com`, EU: `https://eu.dbt.com`, AU: `https://au.dbt.com` |

    Personal access tokens work but are tied to a user account. Service tokens are strongly recommended for production.
  </Accordion>

  <Accordion title="How does the dbt Core CLI plugin authenticate?">
    The `prizm-dbt` CLI plugin authenticates using an API token set as an environment variable:

    ```bash theme={null}
    export PRIZM_API_TOKEN=<your-prizm-api-token>
    ```

    Tokens are generated in **Settings → API Tokens** in Prizm. The token is scoped to your Prizm tenant and is never logged or printed by the CLI. Use `prizm-dbt validate` to verify authentication before your first push.
  </Accordion>

  <Accordion title="Can I connect multiple dbt projects or environments to Prizm?">
    Yes. Create a separate Prizm connector for each project or environment combination. For dbt Cloud, you can scope each connector to specific projects or environments. For dbt Core, use distinct `PRIZM_API_TOKEN` values per project and set the `--environment` flag when pushing artifacts.

    All connectors appear separately in the Source list and have independent job history, settings, and schedules.
  </Accordion>
</AccordionGroup>

## dbt Cloud Setup

<AccordionGroup>
  <Accordion title="Should I use webhooks or scheduled pull for dbt Cloud?">
    **Webhooks are recommended** for all production environments. Benefits:

    * Near-real-time ingestion — Prizm processes a completed run within seconds
    * No polling overhead — fewer API calls to dbt Cloud
    * Predictable, event-driven behavior

    Use **scheduled pull** when:

    * Your network environment does not allow inbound webhook delivery
    * You need to backfill historical run data
    * You are in a regulated environment with strict inbound connectivity requirements
  </Accordion>

  <Accordion title="How do I configure the dbt Cloud webhook?">
    1. In dbt Cloud, navigate to **Account Settings → Webhooks**
    2. Click **New Webhook**
    3. Enter the Prizm webhook URL (shown in your Prizm dbt connector settings)
    4. Select events: `job.run.completed` and `job.run.errored`
    5. Copy the **Webhook Secret** and paste it into Prizm

    Prizm validates each incoming webhook using HMAC SHA256 signature verification. The webhook secret is required — do not skip this step.
  </Accordion>

  <Accordion title="What happens if a dbt Cloud run fails — are artifacts still ingested?">
    It depends on when the failure occurred:

    * **`job.run.errored`** fires early and artifacts may not yet be written. Prizm records the failure signal immediately and retries artifact ingestion with backoff.
    * **`job.run.completed`** fires after artifacts are fully written and available — Prizm ingests everything immediately.

    Even for failed runs, Prizm captures whatever `run_results.json` was produced, which includes the node-level failure details that drive alerting and observability.
  </Accordion>

  <Accordion title="Can I restrict Prizm to specific dbt Cloud projects or environments?">
    Yes. In the connector settings, use the **scope filter** to restrict ingestion to specific project IDs or environment IDs. By default, Prizm has access to all jobs in the connected account.

    After applying a scope filter, only jobs matching the configured project/environment are shown in the job selection list.
  </Accordion>
</AccordionGroup>

## dbt Core Setup

<AccordionGroup>
  <Accordion title="Where in my pipeline should I run prizm-dbt push-artifacts?">
    Run it **after** your dbt command completes — `dbt run`, `dbt test`, `dbt build`, or `dbt docs generate`. The CLI operates purely on filesystem artifacts and does not interact with dbt at runtime.

    ```bash theme={null}
    dbt build --profiles-dir .
    prizm-dbt push-artifacts --project-dir . --target-path ./target
    ```

    If the dbt command fails, you can still run `push-artifacts` — Prizm will ingest whatever artifacts were produced (including a partial `run_results.json` with failure details). Use the `|| true` pattern only if you explicitly want to push even on dbt failures:

    ```bash theme={null}
    dbt build || true
    prizm-dbt push-artifacts --project-dir . --target-path ./target
    ```
  </Accordion>

  <Accordion title="What if manifest.json is missing?">
    `manifest.json` is required. If it is not found at the resolved target path, `push-artifacts` exits with an error and lists:

    * The `--project-dir` and `--target-path` values used
    * The exact file paths checked
    * The corrective action

    Run `prizm-dbt doctor` to diagnose path resolution issues. Common causes: running `push-artifacts` before `dbt run` completes, or providing an incorrect `--target-path`.
  </Accordion>

  <Accordion title="Does prizm-dbt push-artifacts slow down my pipeline?">
    The CLI performs only filesystem reads and a single API call to push artifacts. For typical project sizes, it completes in under 5 seconds. Large projects with very large `manifest.json` files (1M+ nodes) may take 10–30 seconds.

    The command runs after dbt completes — it is not on the critical path of the dbt execution itself.
  </Accordion>

  <Accordion title="Can I push from centralized artifact storage instead of running the CLI per-job?">
    Yes. For regulated environments or teams that already persist dbt artifacts to S3, GCS, or Azure Blob, Prizm supports storage-based ingestion. Configure a storage-based source in the connector settings with the bucket path and polling schedule.

    Storage ingestion is asynchronous and introduces a delay. For near-real-time observability, the CLI plugin push per-run is preferred.
  </Accordion>
</AccordionGroup>

## Artifacts & Ingestion

<AccordionGroup>
  <Accordion title="What is sources.json and do I need it?">
    `sources.json` contains the results of dbt freshness checks — it is generated by running `dbt source freshness`. It tells Prizm whether each source is fresh, in a warning state, or overdue based on the thresholds defined in your YAML.

    * **Without `sources.json`:** Prizm still ingests source metadata (name, schema, freshness thresholds) from `manifest.json` but has no actual freshness check results.
    * **With `sources.json`:** Prizm surfaces freshness violations and SLA breaches directly on source assets.

    To keep freshness data current, run `dbt source freshness` on a schedule and push the resulting artifact with `prizm-dbt push-artifacts` (dbt Core) or ensure your dbt Cloud job includes a freshness step.
  </Accordion>

  <Accordion title="Do I need catalog.json?">
    `catalog.json` is optional. It provides warehouse-introspected column data types and statistics, which enrich the Prizm catalog with physical type information. However:

    * It is only generated by `dbt docs generate` — never by `dbt run` or `dbt build`
    * Prizm infers most column metadata from `manifest.json` YAML definitions without needing `catalog.json`

    Push `catalog.json` when you run `dbt docs generate` in your pipeline. Skip it otherwise — Prizm will not error if it is absent.
  </Accordion>

  <Accordion title="What is semantic_manifest.json and when is it generated?">
    `semantic_manifest.json` contains your dbt Semantic Layer definitions — metrics, measures, dimensions, and saved queries using MetricFlow. It is only generated if your dbt project uses the semantic layer.

    Prizm ingests `semantic_manifest.json` to enrich the catalog with metric definitions and metric lineage. Full metric observability in the Prizm UI is coming in a future release.
  </Accordion>

  <Accordion title="Are historical runs ingested when I first connect?">
    **dbt Cloud:** When using scheduled pull mode, Prizm fetches runs from the lookback window (default: last 24 hours) on the first sync. For historical backfill beyond the default window, contact Prizm Support to configure an extended backfill.

    **dbt Core:** Only artifacts pushed after the connector is configured are ingested. There is no automatic backfill for dbt Core — historical data is not available without artifact re-push.
  </Accordion>

  <Accordion title="What happens if the same artifacts are pushed twice?">
    Prizm deduplicates by artifact hash. Pushing identical artifacts a second time (same `manifest.json` content) does not create duplicate records. New artifacts with different content are ingested and versioned — Prizm keeps a history of artifact versions for lineage and audit purposes.

    For dbt Cloud, the same event delivered multiple times (webhook retries) is handled idempotently — deduplicated by `{account_id, run_id, event_type}`.
  </Accordion>
</AccordionGroup>

## Lineage

<AccordionGroup>
  <Accordion title="How does Prizm build lineage from dbt?">
    Prizm reads the dependency graph from `manifest.json` — specifically the `depends_on` fields for each node. This produces a DAG of:

    **Source → Model → Model → ... → Exposure**

    Prizm then stitches this with warehouse-side lineage (from Snowflake or Databricks) to create an end-to-end graph:

    **Warehouse raw table → dbt Source → dbt Model → Warehouse output table → Tableau Workbook**

    In the lineage view, dbt models appear as transformation edges by default. Enable the **dbt-only toggle** to show models as nodes for a focused dbt-to-dbt dependency view.
  </Accordion>

  <Accordion title="Is column-level lineage supported?">
    Yes, where dbt YAML documentation defines column-level dependencies. Prizm maps column-to-column relationships through the transformation layer.

    Column-level lineage is most complete for models where:

    * Column descriptions are defined in YAML
    * The compiled SQL uses explicit column references (not `SELECT *`)
  </Accordion>

  <Accordion title="A dbt model is not appearing in the lineage graph — why?">
    Check the following:

    1. The model is included in the selected job's artifact scope
    2. `manifest.json` was successfully pushed — check **Settings → Sources → Logs**
    3. The model is not marked as `ephemeral` materialization (ephemeral models are not physical assets and may not appear as lineage nodes)
    4. The upstream warehouse connector (Snowflake, Databricks) is also connected — end-to-end lineage requires both connectors
  </Accordion>
</AccordionGroup>

## Tests & Quality Signals

<AccordionGroup>
  <Accordion title="How do dbt test results become quality signals in Prizm?">
    When `run_results.json` is ingested, Prizm reads the test node results and creates quality signals for each test:

    * **Passing test** → contributes positively to the model's quality score
    * **Warning test** (severity: warn) → surfaces as a quality observation
    * **Failing test** (severity: error) → creates a deterministic alert or issue on the model

    Unlike probabilistic metrics that detect anomalies statistically, dbt test failures are deterministic — if the test fails, there is a known data quality problem.
  </Accordion>

  <Accordion title="Can failing dbt tests create Prizm issues automatically?">
    Yes. Configure **Dependent DQ Runs** in the connector settings to automatically create Prizm issues when specific dbt tests fail. The issue includes the test name, failure details from `run_results.json`, and a link to the failed run.

    From the Tests tab on the dbt Jobs page, use the **Create issue** action on any failing test to create an issue manually.
  </Accordion>

  <Accordion title="Where do I see dbt test results for a specific model?">
    Navigate to the dbt model asset page → **dbt Tests tab**. This shows all tests configured for the model with last 5 run statuses, 30-day pass rate, and last run timestamp.

    Alternatively, navigate to **Source → \[connector] → Jobs → \[job] → Tests tab** to see all tests in scope for a specific job.
  </Accordion>
</AccordionGroup>

## Connector Lifecycle

<AccordionGroup>
  <Accordion title="What happens if a dbt model is renamed or deleted?">
    When new artifacts are pushed, Prizm compares the incoming `manifest.json` against the previously ingested state:

    * **Renamed:** The old model asset is marked as deprecated; a new asset is created with the new name. Lineage history is preserved on the deprecated asset.
    * **Deleted:** The model is marked as deprecated in the Prizm catalog. Deprecated assets are retained for historical lineage and audit purposes.

    Use the **Sync** action from the connector detail page to trigger a manual deprecation check.
  </Accordion>

  <Accordion title="How often does Prizm sync metadata from dbt?">
    | Mode                       | Trigger                                                       |
    | :------------------------- | :------------------------------------------------------------ |
    | dbt Cloud + Webhook        | Immediately on each `job.run.completed` event                 |
    | dbt Cloud + Scheduled Pull | Every 6 hours (configurable)                                  |
    | dbt Core CLI               | Every time `prizm-dbt push-artifacts` is run in your pipeline |
    | dbt Core + Storage         | Configurable poll interval (default: every 6 hours)           |
  </Accordion>

  <Accordion title="A dbt job run is not appearing in Prizm — how do I troubleshoot?">
    Check the following:

    1. **dbt Cloud:** Verify the webhook delivered successfully — check **Account Settings → Webhooks → Delivery Log** in dbt Cloud. If delivery failed, dbt retries up to 5 times.
    2. **dbt Core:** Verify `push-artifacts` ran successfully — check the command exit code and output.
    3. Check **Settings → Sources → Logs** in Prizm for ingestion error details.
    4. Run `prizm-dbt doctor` (dbt Core) to verify connectivity and artifact discovery.
    5. Ensure the job is in the selected job list for the connector — unselected jobs are not ingested.

    If the issue persists, contact Prizm Support with the run ID and ingestion log output.
  </Accordion>
</AccordionGroup>

***

For connection errors and authentication issues, see the [Troubleshooting page](/help/troubleshooting). For definitions of terms used in this FAQ, see the [Glossary](/help/glossary).
