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

# DBT Action Tools

> Manage DBT projects end-to-end: run, test, compile, document, and handle dependencies from automated workflows.

## **Overview**

### **Tool Name**

```json theme={null}
dbt_action
```

### **Purpose**

The **dbt\_action** tool lets you operate DBT projects programmatically. Use it to initialize projects, run and test models, compile SQL, install packages, generate documentation, and coordinate multi-environment deployments.

Local dbt actions that would start dbt are refused inside a Databricks App:
agent-authored Jinja, SQL, and Python models would run unconfined on the App
host. Run the project as a dbt task in a Databricks Job instead. This restriction
is specific to Databricks Apps; see [the App deployment limits](/docs/deployments/Databricks/Genesis-On-Databricks#genesis-as-a-databricks-app).

#### **Functions Available**

1. **`dbt_action`**: *`Executes DBT operations for project management, model execution, testing, docs, snapshots, seeds, and dependency management. Controlled by the action parameter.`*

### Key Features

<Steps>
  <Step title="Run and Test" icon="gears">
    Execute model runs and tests with targets, selectors, and parallel threads.
  </Step>

  <Step title="Compile and Document" icon="file-lines">
    Compile SQL for inspection and generate searchable documentation sites.
  </Step>

  <Step title="Packages and Artifacts" icon="box-open">
    Install dependencies, seed data, snapshot state, and clean build outputs.
  </Step>

  <Step title="Multi-Env Targets" icon="layer-group">
    Switch profiles and targets for development, staging, and production.
  </Step>

  <Step title="Selective Execution" icon="filter">
    Use selectors to run only what you need for faster iteration.
  </Step>
</Steps>

## **Input Parameters for Each Function**

### **`dbt_action`**

**Parameters**

| **Name** | **Definition** | **Format** |
| - | - | :-: |
| **action** | Operation to perform. Common values: `init`, `parse`, `run`, `compile`, `test`, `docs`, `seed`, `snapshot`, `clean`, `deps`, `test_profile`, `PLAN_MIGRATION`, `GENERATE_YAML`, `CONVERT_SQL`. | String (required) |
| **repo\_id** | Git repository that contains the dbt project. Required for most project-scoped actions. | String |
| **profile** | dbt profile name to use for execution. | String |
| **project\_path** | Path to the DBT project directory. | String |
| **profiles\_dir** | Directory containing `profiles.yml`. | String |
| **target** | Target environment defined in `profiles.yml`. | String |
| **models** | Specific model or list of models to run or test. | String or List |
| **model\_name** | Single model to run, test, compile, or generate with `CONVERT_SQL` (appended to **models** when both are provided). Use with `test` right after `run` on the same model. | String |
| **select** | DBT selection syntax to include nodes. | String |
| **exclude** | DBT selection syntax to exclude nodes. | String |
| **query** | SQL or dbt/Jinja query text used internally by query-style handlers such as `execute_query`. | String |
| **sql\_content** | SQL or dbt/Jinja content for generated dbt assets such as models, tests, snapshots, analyses, and `execute_query`. | String |
| **config\_updates** | Structured updates to merge into `dbt_project.yml`. | Object |
| **vars** | Variables to pass to DBT. Pass an object; Genesis serializes it as structured `dbt --vars` JSON/YAML, not shell-style `key=value` text. | Object |
| **threads** | Degree of parallelism. | Integer |
| **full\_refresh** | Force full refresh for incremental models. | Boolean |
| **force\_refresh** | `get_manifest` only. When `false` (default), returns the existing `target/manifest.json` when available. When `true`, deletes that artifact and recompiles so the manifest reflects the current working tree. | Boolean |
| **fail\_fast** | Stop on first failure. | Boolean |
| **store\_failures** | Persist test failures to the database. | Boolean |
| **project\_name** | Canonical name from `dbt_project.yml`, or a legacy child-directory alias. Use `.` for a repository-root project. Required for `create_project` and `delete_project`, and recommended for every project operation. | String |
| **database\_adapter** | Adapter for new projects (for `init`). | String |

### **Repository dbt runtime**

Pin a repository's dbt runtime in `.genesis/dbt-version` when it needs a
different dbt-core or adapter version than the Genesis installation. The file
must contain `dbt-core` exactly once and may contain one exact pin per adapter,
with one package pin per line. Blank lines and comments beginning with `#` are
ignored.

```text theme={null}
dbt-core==1.12.3
dbt-snowflake==1.12.1
```

Supported adapters are `snowflake`, `duckdb`, `sqlite`, `postgres`, `bigquery`,
`redshift`, `databricks`, `spark`, `trino`, and `clickhouse`. Genesis builds an
isolated environment on the first dbt-executing action for a new declaration;
that build can take a few minutes. Later calls reuse the completed environment.
The runtime cache keeps up to 10 completed repository runtimes and may remove
the least-recently-used entries when another runtime is built.

Every dbt-executing response, and `list_system_profiles`, includes a
`dbt_runtime` object:

| Field | Description |
| - | - |
| `dbt_core` | Active dbt-core version. |
| `adapters` | Adapter names mapped to their declared versions. |
| `source` | `bundled` when Genesis uses its installed runtime, or `repo` when it uses `.genesis/dbt-version`. |
| `declaration` | `.genesis/dbt-version` for a repository runtime; `null` for the bundled runtime. |
| `declaration_hash` | Hash identifying the normalized declaration and runtime platform. |
| `ready` | Whether the selected runtime is ready; bundled and successfully built runtimes are `true`. |

Before invoking dbt, Genesis checks `require-dbt-version` in
`dbt_project.yml` against the selected dbt-core version. If it does not match,
the action returns a structured error and does not start dbt.

### **`PLAN_MIGRATION` and `GENERATE_YAML`**

Use `PLAN_MIGRATION` to inspect a related set of views before converting them.
It returns deterministic dependency order, dependencies, cycles, blocked references, detected
sources and source-name collisions, parse failures, and a per-view `relation_map`;
it does not return SQL text. Select the Git repository and dbt project with
`repo_id` and `project_name`.

Both actions accept exactly one locator: a list of repository SQL files, a
repository directory, or a connection and fully qualified view names. Repository
locators require `source_dialect`; for a connection locator, Genesis resolves the
dialect from the connection when it is omitted. Listing a source directory searches
recursively for `.sql` files. A connection locator performs one metadata query per
view, and each located definition is parsed once per call.

| **Parameter** | **Type** | **Default** | **Description** |
| - | - | - | - |
| `source_paths` | Array of strings | `null` | Non-empty list of repository-relative `.sql` view files. Use this, `source_dir`, or `connection_id` with `object_names`. |
| `source_dir` | String | `null` | Repository directory; plans its `.sql` files recursively. Mutually exclusive with the other locators. |
| `connection_id` | String | `null` | Connection containing the views. Use with `object_names`; the pair is mutually exclusive with repository locators. |
| `object_names` | Array of strings | `null` | Non-empty list of `database.schema.view` names, used with `connection_id`. |
| `source_dialect` | String | `null` | SQL dialect such as `snowflake` or `tsql`/`sqlserver`. Required for repository locators; inferred from the connection when available. |

`PLAN_MIGRATION` and `CONVERT_SQL` resolve derived table references against the
selected project's source declarations and model files under its configured model
paths. This reads `dbt_project.yml` and every YAML and `.sql` file under those paths; it does
not use `target/manifest.json`. An explicit `relation_map` still takes precedence.
A declared source replaces a derived `source()` only when its database, schema,
and identifier are all statically known and match the relation. For a two-part
relation, the view's own database must also be known from the connection's
`object_name` or a Snowflake `CREATE VIEW database.schema.view` definition.
Unproven declarations and same-named models are candidates for review, not
automatic mappings; the derived call stays in place. Each `relation_decisions`
entry reports the relation's chosen `call`, `basis`, and possible `candidates`;
the basis is `declared_source`, `derived`, `needs_review`, or `relation_map`.
`PLAN_MIGRATION` substitutes a project's source call into a view's `relation_map`
only when the declared source is proven to match.

`GENERATE_YAML` accepts the same locators. It writes `models/sources.yml` and
one `models/<model>.yml` schema skeleton per view in the selected project. It does
not commit the files, and existing generated targets are not replaced unless
`overwrite=true`.

| **Additional parameter** | **Type** | **Default** | **Description** |
| - | - | - | - |
| `relation_map` | Object | `null` | Optional source/ref overrides keyed by source relation identity. Use explicit source names to resolve cross-view source collisions. |
| `target_dialect` | String | `null` | `snowflake` or `databricks`. Select the generated models' platform so exact-case columns are quoted correctly, reserved column names use the target's spelling in dbt YAML, and source tables in `sources.yml` use the target's spelling and quoting. Omit when models run on the source platform. |
| `overwrite` | Boolean | `false` | Replace existing generated YAML files. |

YAML generation requires every located view to parse successfully. Grain-like
`*_id` and `*_key` columns are reported as candidate grain tests only; no tests
are activated. When a case-insensitive source does not reveal the stored case
needed by the target, `sources_with_assumed_target_case` lists the affected
source identities for review. The response includes the final per-view
`relation_map`; pass each view's map unchanged to its `CONVERT_SQL` call so the
generated models use the same `source()` and `ref()` mappings as `sources.yml`.

```python theme={null}
dbt_action(
    action="PLAN_MIGRATION",
    repo_id="analytics-dbt",
    project_name="analytics",
    source_dir="views",
    source_dialect="snowflake",
)

dbt_action(
    action="GENERATE_YAML",
    repo_id="analytics-dbt",
    project_name="analytics",
    source_dir="views",
    source_dialect="snowflake",
)
```

### **`CONVERT_SQL`**

Use `CONVERT_SQL` to convert one Snowflake or SQL Server view definition into a
generated dbt model. The source comes from either a repository SQL file or a
live database view; provide exactly one locator. `connection_id` may accompany
`source_path` as a source of warehouse column metadata, not as a second locator.
Whenever a connection is supplied, conversion reads column names and types for
base tables not covered by `schema_path`, using one bounded
`INFORMATION_SCHEMA.COLUMNS` query per database and one more per additional 1,000
tables in that database. Each query applies a 50,000-row safety bound, with one
extra row used to detect overflow. This metadata lets
`SELECT *` and type expressions use the warehouse columns; if metadata cannot be
read completely, the affected tables stay unknown and the response includes a
reason. The connection must be Snowflake or SQL Server, and its dialect must
match `source_dialect`. Conversion reads and writes repository files, but does
not commit changes or return the source or generated SQL bodies. When conversion
derives `source()` calls, it also reads `dbt_project.yml` and YAML and `.sql` files
under the project's model paths once per call to resolve project relations and
check declarations. The generated file is
`<project>/models/<model_name>.sql`. Select the repository and dbt project with
`repo_id` and `project_name`.

| **Parameter** | **Type** | **Default** | **Description** |
| - | - | - | - |
| `model_name` | String | Required | dbt model name and generated SQL filename; accepts letters, numbers, and underscores. |
| `source_path` | String | `null` | Repository-relative SQL file path. Use this or `connection_id` with `object_name` as the source locator. May be paired with `connection_id` for warehouse column metadata. Requires `source_dialect`. |
| `connection_id` | String | `null` | Snowflake or SQL Server connection ID for a live view, or to read warehouse column metadata alongside `source_path`. When paired with `source_path`, the connection dialect must match `source_dialect`. |
| `object_name` | String | `null` | Live-view name in `database.schema.view` form. |
| `source_dialect` | String | `null` | `snowflake` or `tsql`/`sqlserver`. Required for `source_path`; inferred from `connection_id` for a live view when omitted. |
| `target_dialect` | String | Required | Output dialect: `snowflake` or `databricks`; controls reserved-identifier spelling in output SQL and source-table spelling and quoting in a proposed `sources.yml`. |
| `relation_map` | Object | `null` | Optional mappings from source relations to dbt `ref()` or `source()` calls. Explicit mappings take precedence over derived schema sources. |
| `schema_path` | String | `null` | Repository-relative JSON or YAML file mapping table names to column-name/type objects; used to expand `SELECT *`. Its table entries take precedence over metadata read through `connection_id`. Give column names exactly as the catalog stores them: ordinary Snowflake columns are uppercase. Lowercase or mixed-case Snowflake names are treated as exact-case quoted columns and require validation during conversion. |
| `materialized` | String | `view` | dbt materialization for the generated model. |
| `overwrite` | Boolean | `false` | Replace the generated model if it already exists. |
| `allow_unverified` | Boolean | `false` | Allow a `differs` verdict or unmapped relation to be written with a validation header. |

For example, convert a SQL file to a Databricks model:

```python theme={null}
dbt_action(
    action="CONVERT_SQL",
    repo_id="analytics-dbt",
    project_name="analytics",
    source_path="ddl/orders_view.sql",
    source_dialect="snowflake",
    target_dialect="databricks",
    model_name="orders",
)
```

To convert a repository SQL file and use Snowflake catalog columns for tables
not listed in `schema_path`:

```python theme={null}
dbt_action(
    action="CONVERT_SQL",
    repo_id="analytics-dbt",
    project_name="analytics",
    source_path="ddl/orders_view.sql",
    source_dialect="snowflake",
    connection_id="snowflake.analytics",
    target_dialect="databricks",
    model_name="orders",
)
```

Genesis checks the transformed SQL's structure before writing. A
`structurally_consistent` verdict permits a write when no other write guard
blocks it. `requires_validation` and `not_checked` results are marked with a
validation header. A `differs` verdict or any unmapped relation blocks the write
unless `allow_unverified=true`; an overridden write is marked for validation.
An existing target file is not replaced unless `overwrite=true`. Sources larger
than 8 MiB are rejected.
Review the returned verdict, reasons, and next step before using the model.
When `connection_id` is supplied, `fetched_metadata_tables` lists the tables
whose column metadata was read. Tables with unavailable or incomplete metadata
remain unknown and are named in `reasons`; review the verdict before using the
model.
For derived `source()` calls, Genesis checks whether the declared source points to
the same database, schema, and identifier as the view; a known mismatch or an
unproven project match prevents a `structurally_consistent` result and changes it
to `requires_validation`, while other verdicts are not upgraded. An undeclared
source is listed in `undeclared_sources`, with a `proposed_sources_yml` proposal
for review; the YAML is never written to the repository. The proposal uses the
target warehouse's source-table spelling and quoting;
`sources_with_assumed_target_case` lists source identities whose stored case could
not be determined from a case-insensitive source and therefore needs review.

### **`parse` and `compile`**

Use these project actions before `run` when you want dbt diagnostics without
executing models:

* **`parse`** reads the entire project and builds its manifest without a
  warehouse round-trip. It surfaces Jinja and YAML errors, unresolved `ref()`
  references, and duplicate model names. It always parses the whole project;
  selectors are not accepted.
* **`compile`** generates the SQL dbt would run without executing a model. It
  can expose quoting, CTE-ordering, and macro-expansion issues that parsing
  does not. Pass `model_name` to compile one model; without it, the whole
  project is compiled. dbt opens a warehouse connection to resolve the target
  database and schema, but does not query table data.

```python theme={null}
dbt_action(action="parse", repo_id="analytics", project_name="orders")

dbt_action(
    action="compile",
    repo_id="analytics",
    project_name="orders",
    model_name="fct_orders",
)
```

### **Project Selection and Repository Layout**

Project-scoped actions use the Git checkout identified by **repo\_id**. Genesis
discovers valid dbt projects at the repository root and in its immediate child
directories; it does not recursively search deeper directories. Use
`action: list_projects` to see each project's canonical `name`, directory,
profile, and the current selection.

For actions that operate on an existing project, pass **project\_name** using the
canonical `name` declared in that project's `dbt_project.yml`. For compatibility,
an immediate child directory name is also accepted when it does not resolve to a
different canonical project name. Use `.` to select a valid project at the
repository root. Project selectors must be a single, trimmed name without path
separators, a drive-colon, or `..`.

`action: create_project` creates a new project in a child directory and rejects
duplicate canonical names or an already-existing directory. A repository-root
project can be selected and used, but `action: delete_project` cannot delete it.

```python theme={null}
dbt_action(action="list_projects", repo_id="analytics")
dbt_action(action="use_project", repo_id="analytics", project_name="orders")
dbt_action(action="run", repo_id="analytics", project_name="orders")
```

### **`test_profile`**

Tests a dbt profile connection without running any models. Use it to verify
connectivity before starting dbt operations.

| **Parameter** | **Type** | **Default** | **Description** |
| - | - | - | - |
| **profile\_name** | String | Automatic profile, when available | Name of the dbt profile to test. In Snowflake metadata mode, the default is `snowflake_profile`; otherwise, Genesis uses the first available profile. |
| **repo\_id** | String | None | Optional Git repository ID used to resolve the profile and test project. |

The response includes the connection test result, profile name and location,
whether the profile is a system profile, connection type and details, target,
dbt debug output, and a success or failure message. Host paths in the profile
location and debug output are returned in redacted or relative form. Connection
diagnostics are available when secret fields such as `password`, `token`,
`private_key`, and `keyfile` contain redaction placeholders such as
`***REDACTED***`; diagnostics containing real secret values are blocked.
Safe diagnostic states such as `is required`, `none configured for profile default`,
and `not set` remain available, including when they appear in structured dbt output;
credential-like values remain blocked.

```python theme={null}
dbt_action(
    action="test_profile",
    profile_name="snowflake_dev",
    repo_id="analytics",
)
```

<Tip>
  Use **select** and **exclude** to scope execution for quick feedback during development.
</Tip>

<Note>
  Genesis validates action-specific parameters before execution. If an action does
  not accept an explicitly provided parameter, the tool returns `success: false`
  with `error: "Invalid parameters for dbt action '<action>'."`,
  `error_class: "tool_error"`, and `error_type: "TypeError"` instead of starting
  the dbt action.
</Note>

<Note>
  `query` and `sql_content` support normal dbt/Jinja template syntax, including
  patterns such as `ref()`, `source()`, `var()`, `config()`,
  `is_incremental()`, `log()`, adapter dispatch, and ordinary control flow. For
  `log()`, the request judge allows only literal message arguments and any
  supplied `info` argument must be a literal Boolean; the message can contain no
  secret, credential, environment, host, account, or absolute-path data. Dynamic
  expressions, concatenations,
  variables, macros, attributes, and sensitive literal content remain deny
  cases. Genesis only runs the Jinja-specific dbt safety checks when the
  submitted text actually contains dbt/Jinja delimiters such as `{{ ... }}` or
  `{% ... %}`.
</Note>

<Note>
  The dbt judge is instructed to respond with exactly `ALLOW` or
  `DENY: <reason_code>`, without a free-form rationale. Category extraction
  tolerates letter case, surrounding whitespace, and a sole code fence already
  accepted by the verdict parser; no user- or model-authored prose is returned.
  A denial keeps
  `block_reason_code: "judge_denied"` and adds `judge_reason_code` with one of
  `secret_exposure`, `environment_access`, `host_details`,
  `file_or_process_access`, `protected_content`, `sandbox_bypass`, or
  `other_policy`. Legacy free-form, missing, unknown, inline-decorated,
  extra-content, duplicate, or conflicting categories use `unspecified` and the
  generic denial summary. Genesis selects
  all public summaries from fixed text and never reflects the raw judge response
  or rejected dbt input to the caller.
</Note>

```python theme={null}
dbt_action(
    action="execute_query",
    repo_id="analytics",
    profile="snowflake_dev",
    sql_content="""
    select *
    from {{ ref('stg_orders') }}
    where order_date >= {{ var('start_date') }}
    """,
    vars={"start_date": "2026-01-01"},
)
```

## **Use Cases**

1. **Automated Transformations**
   Schedule `run` in CI to keep curated models fresh.
2. **Data Quality Gates**
   Execute `test` on pull requests and block merges on failure.
3. **Documentation Portals**
   Generate `docs` and publish the site for analysts and stakeholders.
4. **Incremental Model Hygiene**
   Trigger `full_refresh` during backfills or schema changes.
5. **Dependency Management**
   Pin versions and run `deps` to ensure reproducible builds.

## **Workflow/How It Works**

1. **Step 1: Discover or Create a Project**
   Use `action: list_projects` to inspect the repository, `action: use_project`
   with **project\_name** to select an existing project, or `action: create_project` with a
   new child-directory **project\_name** to create one.
2. **Step 2: Configure Profiles and Targets**
   Provide **profiles\_dir** and **target** for warehouse connections.
3. **Step 3: Install Packages**
   Run `deps` to install packages from `packages.yml`.
4. **Step 4: Run and Test**
   Execute `run` with **select**, **models**, or **model\_name**, then `test` with the same **model\_name** to validate that model's tests.
5. **Step 5: Compile and Document**
   Use `compile` to inspect SQL, then `docs` to build the catalog and site.
6. **Step 6: Operate and Maintain**
   Use `seed`, `snapshot`, and `clean` as needed for datasets and state.

### **Get a Fresh Manifest**

Use `action: get_manifest` to retrieve the project's compiled dbt graph. By
default, Genesis returns the existing `target/manifest.json` without running
dbt, so it may predate files written in the current working tree. Set
`force_refresh: true` whenever you use `get_manifest` to check that your latest
changes parse; Genesis deletes the cached artifact and recompiles the project.

Every response includes `cache_hit`, which is `true` when an existing artifact
was returned without re-running dbt, and `generated_at`, taken from the
manifest's `metadata.generated_at` value or `null` when that value is absent.
If compilation fails, the response sets `success: false` and includes dbt's
own error output so the failure is actionable.

<Note>
  **Process isolation.** Every dbt CLI parse or execution runs in a
  **subprocess**. This keeps Jinja, adapter, and package Python outside the
  Genesis server process, avoids blocking the shared asyncio event loop, and
  ensures file-backed adapter handles die when the child exits. Genesis reads
  the profile as safe YAML only to construct the restricted child environment.

  **Parallel subprocess invocations.** When Genesis runs dbt in a subprocess
  each child receives a minimal invocation-owned environment and a private
  `profiles.yml` copy (directory mode `0700`, file mode `0600`). The child does
  not inherit arbitrary Genesis server variables. The private file contains only
  the selected profile and target, so unrelated credentials never enter the
  child. Exact whole-value Snowflake
  credential references in supported profile fields are materialized safely;
  dynamic, concatenated, defaulted, filtered, nested, or unknown profile
  `env_var(...)` expressions fail closed. Calls within one repository serialize
  because dbt shares project files and `target/` artifacts; different repositories
  remain concurrent without cross-contaminating profile resolution or credentials.
  Genesis bounds how many dbt subprocesses run at once
  with `dbt.max_concurrent_invocations` (default `8`, minimum clamped to `2` at
  runtime) to limit warehouse contention without serializing dbt to
  one-at-a-time; changing the setting requires a process restart.

  Each project-scoped invocation carries an invocation-owned project directory
  resolved from the repository snapshot. For untrusted actions that parse dbt
  project files, Genesis inventories the selected project's parse inputs before
  dispatch and checks that the project and inventory are unchanged before the
  subprocess starts. If the project changes during this safety preflight, the
  action fails and should be retried.
</Note>

## **Integration Relevance**

* **data\_connector\_tools** for connectivity checks and schema exploration.
* **git\_action** to version models, macros, and tests.
* **file\_manager\_tools** to store artifacts and publish generated docs.
* **project\_manager\_tools** to track DBT tasks and milestones.
* **databricks\_action** when models rely on Databricks execution.

## **Configuration Details**

* Ensure `profiles.yml` contains correct credentials for each **target**.
* When using `setup_profile`, do not put direct `env_VAR` or `${VAR}` references
  in credential fields. Genesis rejects those references instead of resolving
  them from the server environment; use a stored secret or the isolated
  `env_var(...)` profile flow described below.
* Tune `dbt.max_concurrent_invocations` (default `8`, env var
  `GENESIS_DBT_MAX_CONCURRENT_INVOCATIONS`) when many agents run dbt builds in
  different repositories — it caps concurrent subprocesses to limit warehouse
  contention (values below `2` are clamped up at runtime). Calls in the same
  repository serialize around their shared files. Restart Genesis after changing
  this setting.
* Tune **threads** based on warehouse capacity and model complexity.
* For Snowflake query attribution and custom dbt `query_tag` values, see
  [Identify Twin scanner queries](/docs/Integrations/Data%20Sources/Snowflake/Snowflake#identify-twin-scanner-queries).
* Pin package versions in `packages.yml` for reproducible builds.
* For trusted automation that needs non-secret `env_var(...)` values, configure
  exact name/value pairs in `dbt.safety.trusted_env_vars`. Server process
  environment variables are never inherited; config-side `env_VAR` and `${VAR}`
  references are rejected rather than resolved, and runtime-control names are
  reserved.
* For file-backed DuckDB targets, point `profiles.yml` at the same `.duckdb`
  file Genesis uses for agent queries only when both workloads can share the
  database; each dbt child releases its file handle when it exits, but a
  concurrent dbt child still needs the file unheld for the duration of its run.

<Warning>
  DBT runs execute SQL on your warehouse. Choose the correct **target**, set **threads** responsibly, and use **full\_refresh** only when necessary.
</Warning>

<Warning>
  Genesis applies dbt input and output safety checks around execution unless the
  project is on the `dbt.safety.trusted_projects` allowlist (see
  [Advanced Settings — dbt safety settings](/docs/Setup/Advanced-Settings#dbt-safety-settings)).
  A trusted match on `project_name` or `repo_id` skips the static blocks and LLM
  judge; it does not inherit the server environment. Only non-secret values
  explicitly configured in `dbt.safety.trusted_env_vars` are available to the
  trusted project's `env_var(...)` calls. Host-path and credential redaction in
  `dbt_action` always still runs.
  Trusted project-name matches require one unique canonical project name within
  the repository; duplicate names fail closed rather than bypassing the safety
  checks.
  Untrusted projects: literal secret indicators or sensitive host paths in
  `query`, `sql_content`, `config_updates`, or dbt project files under
  `models/`, `macros/`, `tests/`, `snapshots/`, or `analyses/` can be blocked
  even when the input is plain SQL with no Jinja. Inputs or returned logs that
  try to expose env vars, host files, session tokens, `bot_storage`,
  `AWS_SECRET_ACCESS_KEY`, `PRIVATE KEY`, or other exposed credential values can
  fail with a generic safety error. Caller-supplied credentials are excluded from
  the return-side safety judge's request summary and from dbt diagnostic error
  context. If a configured dbt credential cannot be resolved, the tool returns a
  generic credential-resolution error with `error_type: "SecretResolutionError"`
  rather than exposing the resolver's exception details. Redacted, masked, hidden,
  removed, omitted, scrubbed, or sanitized placeholder values are allowed in
  returned output. The safety judge accepts a verdict when `ALLOW` or `DENY`
  opens a line, including common Markdown or code-fence decoration and a trailing
  separator such as `:`, `-`, `–`, `—`, or `.`. A line-start `DENY` always blocks;
  an `ALLOW` is accepted only when no `DENY` appears anywhere in the raw verdict.
  Verdicts with only preamble or prose, and other ambiguous or unparseable
  verdicts, fail closed with `block_reason_code: "judge_unparseable"`. The raw
  judge verdict is retained in the structured safety audit record for operators,
  but is not returned to the caller.
</Warning>

## **Limitations or Notes**

1. Requires DBT CLI availability in the execution environment.
2. Large graphs can consume significant compute, scope with **select**.
3. Adapter features vary by warehouse; validate per adapter.
4. Network and warehouse quotas can impact execution times.

### **Output**

* **Command Execution**: Logs with status, timings, and summary counts.
* **Model Results**: Per model status and row counts.
* **Test Results**: Pass or fail with failure details.
* **Docs and Compile**: Generated site files and compiled SQL outputs.
* **Runtime**: dbt-executing responses include `dbt_runtime`; see [Repository dbt runtime](#repository-dbt-runtime) for the declaration format, response fields, and version preflight.
* **Errors**: On failure, responses set `success: false` and populate `error` from the tail of captured dbt output when the runner leaves it empty — so agents always get an actionable summary. Check `error_class` to distinguish a genuine dbt or dispatch failure (`tool_error`) from a safety policy block (`policy_block`); the [tool-call endpoint reference](/docs/Genesis-API/Tool-Call-Endpoint#common-status-codes) documents the associated block reason fields. Full output may also appear in `logs` (or a spill-to-file hint when inline size is capped); read spilled logs with `git_action(action='read_file', ...)`. `get_manifest` also returns dbt's compile error output instead of a generic manifest-generation error. Credential-resolution failures use a fixed generic message and `error_type: "SecretResolutionError"`; credential values and resolver exception details are not included in the response context.
