dbt-labs/dbt-core · error
Failed to create relations from nodes
Error message
Failed to create relations from nodes
What it means
`create_relations_from_executed_nodes` (crates/dbt-adapter/src/metadata/metadata_adapter.rs:134) builds a relation from each executed node's database/schema/alias/quoting and calls `.expect("Failed to create relations from nodes")`. The relation constructor is infallible in normal use, so a panic means the node produced a relation string the constructor rejects (e.g. invalid identifiers or incompatible quoting/database layout).
Source
Thrown at crates/dbt-adapter/src/metadata/metadata_adapter.rs:134
relevant_ids.insert(unique_id.clone());
// Include direct source parents from the parent map
let parents = &node.base().depends_on.nodes;
relevant_ids.extend(parents.iter().filter(|p| p.starts_with("source.")).cloned());
}
relevant_ids
.iter()
.filter_map(|uid| resolved_state.nodes.get_node(uid))
.map(|node| {
create_relation(
adapter_type,
node.database(),
node.schema(),
Some(node.alias()),
None,
node.quoting(),
)
.expect("Failed to create relations from nodes")
.into()
})
.collect()
}
/// Create schemas if they don't exist
#[allow(clippy::type_complexity)]
fn create_schemas_if_not_exists(
&self,
state: &State<'_, '_>,
catalog_schemas: Vec<(String, String, String)>,
) -> AdapterResult<Vec<(String, String, String, AdapterResult<()>)>>;
// =========================================================================
// Async I/O methods - use _inner pattern for recording
// =========================================================================
/// List UDFs under a given set of catalog and schemas (implementation).View on GitHub (pinned to 0267ce9170)
Solutions
- Inspect the failing node's database/schema/alias values for emptiness or invalid characters and fix the node config
- Replace `.expect` with proper error propagation (`ok_or_else` -> AdapterError) so one bad node doesn't abort the whole batch
- Validate relation identifiers before rendering SQL (quote/escape per warehouse rules)
- Check the profile/target configuration that supplies database and schema defaults
Example fix
// before
.expect("Failed to create relations from nodes")
// after
.ok_or_else(|| AdapterError::new(
AdapterErrorKind::UnexpectedResult,
format!("failed to build relation for node {}", node.name()),
))? Defensive patterns
Strategy: validation
Validate before calling
// validate node parts before relation creation assert!(!node.database().is_empty() && !node.alias().is_empty(), "node missing database/alias");
Type guard
fn relation_parts_present(node: &ExecutedNode) -> bool {
!node.database().is_empty() && !node.alias().is_empty()
} Try / catch
std::panic::catch_unwind(AssertUnwindSafe(|| create_relations_from_executed_nodes(&nodes)))
Prevention
- Validate database/schema/alias in node configs early
- Check profile target supplies database and schema defaults
- Escape/quote identifiers per warehouse rules
- Fail fast with a clear error for empty node fields
When it happens
Trigger: Creating relations from executed model nodes whose database/schema/alias combine into an invalid or empty relation identifier, causing the relation constructor to return None/Err.
Common situations: Nodes with empty alias or schema due to config mistakes (e.g. missing schema in target/profile); identifiers containing characters the relation builder disallows; custom materializations that leave node fields unset.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Schema not found for canonical FQN: {}
- `EnterGuard` values dropped out of order. Guards returned by
- {e} {:?}
- {e}
- inconsistent park state; actual = {actual}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/71d0e0275af1b440.
Report an issue: GitHub.