github dbt-labs/dbt-core v2.0.0-beta.1

pre-release6 hours ago

2.0.0-beta.1

Released August 10, 2026

Features

  • Provide option of using default profile.yml during init
  • Allow continue running children on parent error
  • Implement selector selector method
  • Support overloaded UDFs via overrides block in function YAML
  • Implement dbt state explain in Fusion
  • Test optimization to skip provably redundant tests
  • Add cargo xtask apply-ci-goldies to fetch CI logs via gh and apply golden-file patches onto the current worktree.
  • Support Databricks Azure service principal (Microsoft Entra ID) authentication via azure_client_id/azure_client_secret (auth_type azure-client-secret), matching dbt-core/dbt-databricks
  • Add Docker and docker compose support for self-hosting the dbt docs server (dbt docs serve)
  • Clickhouse: Add missing configurations for ClickHouse table materialization (#14585)
  • Add --infer-schemas, --skip-type-checking, and --show-sources flags for catalog-free binding to bind SQL without introspection.
  • Support pseudocolumns (e.g. BigQuery's _FILE_NAME) in unit tests
  • Add machine-readable JSON output for dbt --format json --version
  • Add the dbt.import_ctes (DBT01) lint rule, requiring every ref()/source() to be imported through a top-level CTE
  • Add opt-in Redshift grants support for groups and roles
  • Support dbt node selection (--select/--exclude/--selector) for lint and format in both symbolic and rendered render modes
  • Add unit tests to the Jinja graph object
  • Add error_code and error_message fields to the dbt login Vortex telemetry event
  • dbt State: speculatively submit models, snapshots, and data tests while the dependency last-modified prefetch is still in flight, so nodes no longer block on the full prefetch before a cache decision
  • Report the dbt invocation ID (and dbt platform run ID when present) with dbt State telemetry so runs can be correlated end to end
  • Skip provably redundant accepted-values data tests
  • Add undocumented dbt internal get-distribution-info command for resolving dbt release-channel and distribution info, falling back to <dbt> --version to infer generation and distribution when a target dbt doesn't support the command itself. --all now discovers every dbt on PATH concurrently and skips the doomed internal probe for non-native (script) installs, cutting multi-install discovery time substantially. Each probe is now bounded by a wait/graceful-terminate/forceful-kill timeout so a hung or badly-behaved dbt on PATH can't stall or block discovery indefinitely. When a Homebrew-tap conflict identifies an already-installed dbt Cloud CLI, get-distribution-info now also reports its uninstall command
  • When a Snowflake metadata warehouse is configured, dbt State now fetches table last-modified freshness metadata with one query per schema in parallel (bounded by the configured thread count), instead of running the per-schema dumps sequentially
  • Support dbt State configs on snapshots and data tests
  • [BigQuery] Link to docs for Storage API errors (#15544, #13600)

Fixes

  • Fix stale sourced_remote schema cache for DuckDB adapter causing unit test fixture column mismatches after model schema changes
  • Fixed file-system reserved characters in FQNs from being included in paths by replacing them with double underscores.
  • Always show a fallback line in the Test Failures summary for failed tests, even when no diff table or stored failures relation is available
  • fix: explicitly set default empty variable for $SHELL so that the script will not end while setting the $SHELL.
  • Treat unresolvable Snowflake views as stale for dbt State reuse decisions.
  • Fix typo in the try_or_compiler_error type-check warning message ("a optional argument argument" -> "an optional argument") (#15323)
  • Allow state-org-id in the dbt-cloud block of dbt_project.yml.
  • model.batch.event_time_start and model.batch.event_time_end are now datetime objects in Jinja context, enabling .strftime() and other datetime methods to work as in dbt Core
  • Fix state modified selection for hook and test alias diffs
  • Preserve lowercase Snowflake SHOW and DESCRIBE result column names so dbt_constraints can access run_query columns and rows.
  • on-run-end hooks can now call datetime methods such as .replace(tzinfo=...) and .strftime(...) on result.timing[*].started_at and .completed_at fields.
  • Fix the @ graph operator (and the equivalent childrens_parents YAML selector) returning an empty set when applied to a leaf node. It now correctly returns the node together with its ancestors. (#15280)
  • Fix source freshness failing entirely when a single source errors in the MapReduce aggregation phase. (#15385)
  • Make dbt State disable itself and continue when accounts are disabled or locked, while keeping user-actionable auth errors fatal.
  • dbt init no longer leaves a stale authenticator field when switching from SSO/MFA to Password or Key pair authentication for Snowflake profiles (#15378)
  • Normalize BigQuery model context column data types when contract alias_types is enabled (e.g. FLOAT -> FLOAT64), matching dbt Core. (#14097)
  • Versioned models: per-version docs (show/node_color) now override top-level model docs, matching dbt-core behavior
  • Force dbt State cache misses for BigQuery external table sources whose metadata timestamps do not reflect backing data changes.
  • [Redshift] Honor the is_serverless profile flag (plus serverless_work_group and serverless_acct_id) so Serverless workgroups reached via a non-serverless host (e.g. an SSM port-forward) are treated as Serverless and no longer require cluster_id, matching dbt Core.
  • Generic tests with auto-truncated names now correctly set config.alias and unrendered_config.alias in the manifest, matching dbt-core behavior
  • Populate warning/error code and name in legacy Core-compat JSON log output
  • Support non-ASCII Jinja macro names in Fusion parsing.
  • Match dbt-core by ignoring the legacy tests alias on versioned model versions.
  • Accept Core manifest value shapes. (#15169, #14570)
  • BigQuery: emit the expiration_timestamp relation option (and render options in dbt-core's insertion order) when hours_to_expiration is present but renders to a non-numeric value such as null, matching dbt Core instead of dropping the option
  • Fix config precedence bug where +schema: null or +database: null in dbt_project.yml incorrectly overrode schema/database values set in schema.yml properties files
  • (dbt-auth): Bigquery: Better error handling and messages to guide uses using api_endpoint with emulators and other strict hosts (#14615)
  • Do not use unit test configs for state:modified determination
  • Fix macro manifest parity for materialization supported languages.
  • [BigQuery] Drop Storage API permission requirement when listing schemas (#14631)
  • (state:modified) Restore rendered comparison of freshness in source nodes
  • (adapters/redshift) sync v1 Jinja macros using dbt-labs/dbt-adapters@9fce78f
  • Include file paths on missing doc macro warnings and suppress empty-path duplicates.
  • Retire the last unrendered-enhanced key comparisons in state:modified (in function nodes)
  • (adapters/redshift) relation cache tracks relations' dependencies; bring the view materialization in sync with v1 (#15467)
  • Match dbt-core unique filter behavior for modules.datetime.date values.
  • Fixed a TOCTOU race in dbt-loader that could panic when a dbt project was loaded concurrently from multiple threads, by initializing DISPATCH_CONFIG with get_or_init instead of a check-then-set
  • Fix dbt State schema-level freshness dump returning empty for Snowflake schemas with lowercase names in dbt_project.yml, causing an unnecessary fallback to per-relation freshness queries.
  • Preserved successful Snowflake freshness metadata when another database batch is inaccessible
  • Support Redshift statement cancellation. Now pressing Ctrl-C during a dbt run will abort the statements server-side and early exit. (#15494)
  • Added DBT_RESOURCE_TYPES / DBT_EXCLUDE_RESOURCE_TYPES env variables to dbt build --help
  • (state:modified) Stop treating function tags/group changes as config modifications on the sparse-fallback comparison path
  • dbt-sa-cli force defer introspective nodes on compile (#15569)
  • Count failed unit tests correctly in interactive progress output
  • Fix the @ graph operator (and the equivalent childrens_parents YAML selector) returning an empty set when applied to a leaf node. It now correctly returns the node together with its ancestors. (#15280)
  • dbt retry now runs exactly the nodes recorded as retryable in run_results.json, matching dbt-core, instead of re-expanding that selection with eager indirect selection. It no longer pulls in tests the original command never ran: data tests attached to a retried model when retrying dbt run, already-passed unit tests, or tests excluded by the original --indirect-selection / --exclude (which could also turn a passing retry into a failure when the excluded test had a second, unbuilt parent).
  • [BigQuery] Allow get_relation to find tables in hidden datasets (#14635)
  • Fix range() returning incorrect values when using negative steps. (#15585)
  • LSP: Fixed LSP panic when a 'dbt clean' was invoked
  • Skip post-success warehouse metadata refreshes for dbt State executions without confirmation tokens when a heuristic timestamp is available.
  • Treat Snowflake TEMPORARY relations as tables in list_relations to prevent a panic when SHOW OBJECTS returns a session-scoped temp table
  • Fix BigQuery unit test CTE aliases for quoted project identifiers.
  • Correct the naming of install_prerelease field in packages.yml
  • Clear stale dbt State final metadata after successful no-confirmation executions so downstream misses use the planned prefetch path, including BigQuery schema prefetch.
  • Fix state:modified false positives for semantic models and metrics: restore the SemanticEntity/semantic-model-config manifest round-trip, load previous-state metrics for comparison, and align metric content comparison with dbt-core.
  • Align inherited +tags order with dbt-core (parent then child, no alphabetical sort) (#15590)
  • Skip static analysis for models with a custom materialization.
  • Windows install script no longer overwrites an existing PowerShell $PROFILE with an empty file when setting the dbt alias
  • Database (and other execution-time) errors during test execution now always surface as a run error, independent of the test's severity config; severity only governs successfully-returned test results, matching dbt Core (#15514)
  • Emit unsupported engine environment variable and source status warnings through structured tracing
  • reject incremental models with contract enforcement and invalid on_schema_change (##14572)
  • Fixed cancelled models sometimes being reported as Passed or Succeeded
  • Match dbt Core's fromjson fallback behavior by returning the default value, or None, when JSON parsing fails
  • Render {{ this }} as the physical relation instead of a self-referential CTE for ephemeral models, matching dbt-core (#13961)
  • Snowflake Horizon (built-in) iceberg tables no longer fail to compile when a resolved transient config is present., whether inherited from a project-wide default or set explicitly on the model.
  • INT64 partitioned tables now use the proper partition bucket names. (#15464)
  • BigQuery driver used to crash whenever the resulting dataset contained INT64 pseudocolumns. (#15464)
  • Prefer DBT_ENGINE_* environment variables over their legacy DBT_* aliases when both are set
  • Always emit the full set of per-node keys in run_results.json (including failures as null for skipped nodes), matching dbt Core and fixing downstream consumers such as the dbt-artifacts package
  • Fixed empty flag issue where no real data is being written
  • Fixing dbt clone message for ephemeral models, should be skipping instead of giving No relation found output
  • Keep dbt State initialization available when schema metadata prefetch fails by caching unknown freshness for the affected schema group.
  • Honor a null config in the dbt_project.yml models hierarchy so it clears a value inherited from a higher level (starting with hours_to_expiration), and ensure a more-specific level's value always overrides a cleared parent, matching dbt Core precedence
  • Naive Python datetime values now render %z and %Z as empty strings in strftime(), matching Python behavior.
  • Fixed agate tuple rendering in Jinja output to avoid an extra trailing comma before the closing parenthesis.
  • Support ConstraintNotEnforced and ConstraintNotSupported in warn_error_options, and emit these warnings when an adapter does not enforce or support a model/column constraint
  • Honor the project segment when resolving 3-part ADO private packages (org/project/repo) so the correct provider configuration is selected when multiple projects share an org (#12989)
  • Normalize deprecation_date to a timezone-aware timestamp in manifest.json so dbt Core consumers can parse it without a TypeError
  • Preserve cached dbt State data test warning outcomes when replaying reused test results.
  • [BigQuery] Detect cluster_by order changes only when fields change (#9923)
  • Show with ephemermal ref missing rendered ephemeral node (#15260)
  • Fold the microbatch event-time window into the run-cache key so re-running a microbatch model over an unchanged window is a whole-model no-op while a different window executes
  • Fix source table-level config incorrectly overriding root project overlay for dependency package sources
  • Support model.update() in dbt Jinja model contexts.
  • Fix cross-package macro attribute-access calls missing from depends_on.macros
  • Fix macro nodes always having empty depends_on.macros in manifest
  • Support --resource-type and --exclude-resource-type filters for dbt test.
  • Preserve microbatch event-time filtering when ref and source are overridden through the builtins namespace
  • Preserve default schema on dbt State enriched SQL requests, including data tests without target tables.
  • Bring dbt-state's semantic-extras key list up to parity with the Python query-cache client, wiring the newly-added model/snapshot/test config keys (contract, constraints, cluster_by, unique_key, grants, event_time, sql_header, lookback, partition_by, table_format, and dialect-specific attributes) into the actual cache-key extraction so config changes to these fields trigger re-execution instead of a stale NO-OP
  • Submit standard incremental models that use a custom incremental_strategy macro to dbt State as DBT_CUSTOM instead of warning and forfeiting caching
  • Render a source's loaded_at_query through Jinja during dbt State prefetch so macros (and {{ this }}) resolve before the freshness query reaches the warehouse (#15499)
  • Fix SQL mismatch false positives for dbt_date and dbt_utils macros (e.g. date_spine) in Time Machine replay by treating read-only execute calls (SELECT/SHOW) as unordered across segment boundaries, and removing hardcoded AdapterType::Snowflake from replay argument matching
  • Fix BigQuery snapshot ALTER TABLE ... ADD COLUMN to include the database qualifier
  • dbt State: Start sending clone_chain_depth_limit to the server to help make correct clone decisions
  • Fix unit test overrides.macros.run_started_at raising unknown method strftime errors
  • Fix dbt State clearing a table's cached last-modified epoch after its own submit decision (even when reused/skipped), which caused a spurious per-node freshness fallback query and StateServiceWarn (dbt1410) warning for any downstream model that ref()s it directly, on every build.
  • Evict a node's cached last-modified epoch and existence after it executes without a confirmed dbt State request because the request failed, so downstream nodes in the same invocation are not incorrectly skipped based on stale freshness
  • Unit test fixtures with invalid columns now error instead of warning and passing
  • Fix spurious UnusedResourceConfigPath warning for models disabled via dbt_project.yml on incremental/partial-parse runs, caused by disabled nodes not being seeded from the parse cache before the unused-config check ran. (#15348)
  • Omit BASE_LOCATION on Snowflake iceberg and dynamic iceberg tables when the resolved external_volume is unset or explicitly set to the reserved 'SNOWFLAKE_MANAGED' value, so managed-storage Iceberg tables no longer fail with a BASE_LOCATION compilation error
  • Calls to Snowflake stored procedures that return TABLE no longer panic with a driver fatal error (#15661)
  • Jinja-render semantic layer YAML (metrics, saved queries) like other schema.yml properties, excluding only metric filter and saved_queries.query_params.where, which stay verbatim for MetricFlow (#14468)
  • Fix dbt State on production deployments: exclude exposures from the freshness prefetch, which generated invalid metadata SQL from their empty database and schema; honor an explicit opt-out over DBT_ENGINE_MANAGE_STATE so --no-manage-state and flags.manage_state: false take effect; and resolve dbt State on dbt compile and dbt show, which previously ignored the flag (#15374)
  • Skip static analysis for custom materializations that shadow a built-in name (e.g. table, incremental), matching the existing behavior for novel-named custom materializations. Fixes malformed SQL when such a materialization guards graph.nodes introspection behind {% if execute %}.
  • Databricks: detect a changed view definition so that view_update_via_alter runs ALTER VIEW ... AS before COMMENT ON COLUMN when a new column is added (#15583)
  • (fix adapters/databricks) don't treat empty tokens as PATs
  • Exclude the Fusion-only static_analysis config from state:modified comparisons for sources, snapshots, functions, and analyses, matching dbt-core (which has no such field)
  • Restore write-barrier consumption by method name only in Time Machine semantic replay; SQL content validation happens downstream via the existing sanitizer-aware check, avoiding false-positive "no recorded event" failures for writes with legitimate dynamic content (e.g. audit-log timestamps)
  • Avoid panicking on out-of-range timestamps (e.g. far-future TIMESTAMP_NTZ sentinel values) when converting Arrow timestamp arrays to Jinja values; treat them as null, consistent with other date/time converters
  • [BigQuery] Allow list_relations to list relations under hidden datasets
  • Use dispatch-based custom-materialization detection in the run cache (model execution type and parse-failure dependency extraction), so models whose built-in materialization is shadowed by a user-defined macro are consistently treated as custom.
  • Support Snowflake TIME columns in unit test fixtures.
  • Fail fast instead of hanging for 300s when dbt State needs to authenticate but no interactive terminal is available (CI, batch replay); this now surfaces as a graceful skip like other dbt State unavailability cases instead of a hard AuthFailed error
  • Stop generate_*_name macros from swallowing raise_compiler_error calls (#15611)
  • dbt retry now treats a warn node as retryable only when the retry invocation passes --warn-error, matching dbt-core. Previously retry always re-ran warned nodes, so a severity: warn test that kept warning was re-run on every retry and --warn-error had no effect. The 'Retrying N nodes' banner also no longer describes retried nodes as failed.
  • state:modified no longer reports a phantom meta change when a config key was relocated into +meta between the previous-state manifest and the current project (e.g. by dbt-autofix, when a config key has no field on Fusion's typed config struct)
  • Jinja in macro YAML properties is now evaluated once per parse instead of twice, so a description or meta value that calls something with a side effect (e.g. log()) no longer runs it twice.
  • Jinja in a macro's description is now evaluated in dbt Core's restricted documentation context, so calling a project macro from a description is an error instead of being executed and inlined into the description
  • A failed on-run-end hook no longer records successfully-materialized models as error in run_results.json. Models that materialized keep their success status, and each on-run-end hook is now recorded as its own operation.. node (matching dbt-core). As a result dbt retry finds nothing to retry after an on-run-end failure instead of rebuilding the entire project.
  • Recognize constraints as a valid model config() key (previously rejected as an unrecognized key), matching dbt-core's behavior of accepting it without enforcing it — only the schema.yml constraints: model property is enforced. Cache-invalidation systems like dbt State/Run Cache now correctly react to constraint changes authored either way.
  • Fix dbt State run-cache extraction treating a custom materialization's compiled SQL as having zero upstream dependencies when it is a bare qualified relation reference (e.g. some BigQuery custom materializations), causing the node to be skipped forever instead of being invalidated by real upstream changes
  • Avoid an unnecessary speculative dbt State request when the dependency last-modified prefetch completes during view-definition traversal; readiness is re-checked at the last responsible moment so the node submits non-speculatively with resolved epochs instead.
  • Report a mismatch between the dbt-cloud project-id in dbt_project.yml and ~/.dbt/dbt_cloud.yml up front, naming the project-id and pointing at the offending line, instead of failing later with a generic missing-configuration error (#14454)
  • Match read-only compile-time probes such as dbt_utils.date_spine out of order during Mantle replay, and widen the Databricks probe handling
  • A docs block whose name is not a valid identifier no longer discards every other docs block in the same file
  • The as_bool filter now passes its value through unchanged when rendering text (SQL, macros), matching dbt-core: "true" | as_bool renders true instead of True, and an expression such as target.name in ['dev'] | as_bool — which Jinja parses as a containment check against the filtered list — no longer fails with "cannot perform a containment check on this value"
  • Name the undefined argument when a config() value is undefined
  • Fix timedelta.total_seconds() truncating to whole seconds, so sub-second durations no longer return 0.0. Also makes non-zero sub-second timedeltas truthy and normalizes days/seconds/microseconds and str() for negative durations, matching Python. (#15756)
  • Defer semantic model relations to production when only the semantic model's YAML changed but its underlying model was not rebuilt
  • Snowflake freshness prefetch (and other bulk metadata queries) now switches to a dedicated metadata warehouse once per connection instead of once per query, cutting warehouse-switch overhead for large batches
  • Speed up package-qualified macro name resolution (elementary.foo, dbt_utils.bar). Membership in a package's macro list was a linear scan on every access, so the cost grew with the number of macros in the package; it is now a hash lookup. On a project using elementary (~1000 macros), this takes an on-run-end hook that iterates the graph from ~1.6x slower than dbt Core to parity. (#14455)
  • Fault-isolate per-macro typecheck calls so a single macro body that panics inside the type-inference VM no longer crashes the whole parse/run
  • Preserve unit test CTE closures after trailing SQL line comments.
  • Report a clean, located error for a zero-argument ref() or source() instead of panicking during compilation. Because the panic happened at compile time, one malformed call previously took down parsing for every other model and macro in the project.

Under the Hood

  • Add support for dbt-databricks adapter function recordings
  • Record complete lifecycle telemetry for every local tool-call attempt.
  • Parse the DBT_ENGINE_USE_V2_PARSER environment variable as a recognized no-op
  • Refactor CompileBaseCtx to remove the DummyConfig config slot; introduce OperationCtx and typed builders build_compile_base_ctx / build_operation_context
  • state:modified config-comparison conformance - refactoring retrospective and agent instructions
  • add typed flatten composition seam to node ctxs
  • Complete the move from local LiteLLM to native provider routing with privacy-safe telemetry.
  • Centralize BigQuery unit-test cast check in reusable TypeOps method
  • add typed build_run_node_ctx seam and migrate dbt-freshness onto it
  • Parse the --use-v2-parser / --no-use-v2-parser CLI flags as a recognized no-op
  • Migrate Redshift dbt-auth to the standard IR/pipeline configuration architecture used by other adapters
  • Replace per-struct helper functions in config DefaultTo impls with a DefaultTo trait and ReplaceIfNone marker, eliminating default_hooks, default_quoting, default_docs, default_meta_and_tags, default_classifiers, default_packages, default_column_types, and default_to_grants helpers
  • AdapterResponse is now backed by a ValueMap. This paves the way to adding arbitrary keys to AdapterResponse.
  • (snowflake, redshift) respect quoting configs literally when building the metadata queries
  • dbt State: port DbtNodeState submission from Python to Rust
  • Introduce DefaultTo trait and derive macro for config inheritance
  • Standardize listify-newtype serialization by generating Serialize/Deserialize impls via macro instead of per-field serde attributes
  • Add a run-cache unit test pinning that a model materialized as a built-in name (e.g. table) whose materialization macro is shadowed by a user-defined macro is classified as a custom (DBT_CUSTOM) execution type.
  • dbt State: port persist_docs semantic extra

Security

  • Warn when a package tarball contains symlink, hard link, or device entries; these will stop being extracted in a future release. Also upgrade astral-tokio-tar from 0.5.6 to 0.6.4 (RUSTSEC-2026-0066, RUSTSEC-2026-0112, RUSTSEC-2026-0113, RUSTSEC-2026-0145)

Contributors

Don't miss a new dbt-core release

NewReleases is sending notifications on new releases.