dbt-labs/dbt-core · error
get_temp_relation_path: relation.identifier is required
Error message
get_temp_relation_path: relation.identifier is required
What it means
An InvalidOperation minijinja error from get_temp_relation_path stating that `relation.identifier` is required. The callable derives a temp-relation path from database + identifier; a missing, null, empty, or non-string identifier makes path construction impossible, so the error is raised.
Source
Thrown at crates/dbt-adapter/src/adapter/mod.rs:4178
.ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"get_temp_relation_path: relation.database is required",
)
})?;
let identifier = relation_val
.get_attr("identifier")
.ok()
.and_then(|v| {
if v.is_undefined() || v.is_none() {
None
} else {
v.as_str().map(|s| s.to_owned())
}
})
.filter(|s| !s.is_empty())
.ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"get_temp_relation_path: relation.identifier is required",
)
})?;
let path = self
.get_temp_relation_path(&database, &identifier, batch_id)
.map_err(minijinja::Error::from)?;
Ok(Value::from_object(path))
}
// major: int, minor: int
"compare_dbr_version" => self.compare_dbr_version(state, args),
// config: dict, model: dict, is_incremental: Optional[bool] = False
"compute_external_path" => self.compute_external_path(state, args),
// config: dict, tblproperties: Optional[dict] = None
"update_tblproperties_for_uniform_iceberg" => {
self.update_tblproperties_for_uniform_iceberg(state, args)
}
// config: dictView on GitHub (pinned to 0267ce9170)
Solutions
- Set a non-empty string identifier on the relation before calling (e.g. `this.identifier`).
- Fix the macro/factory that builds the relation so identifier is always populated.
- Guard the call site: skip or default the temp path when identifier is falsy.
- Check quoting/rendering so identifier isn't rendered away before the call.
Example fix
// before
{% set rel = api.Relation.create(database=target.database) %}
{% set path = get_temp_relation_path(rel, batch_id) %}
// after
{% set rel = api.Relation.create(database=target.database, identifier='my_table') %}
{% set path = get_temp_relation_path(rel, batch_id) %} Defensive patterns
Strategy: validation
Validate before calling
{% if relation.identifier is not defined or not relation.identifier %}
{% do exceptions.raise_compiler_error('relation.identifier required for temp relation path') %}
{% endif %} Type guard
fn has_identifier(v: &Value) -> bool {
v.get_attr("identifier").ok().and_then(|i| i.as_str().map(|s| !s.is_empty())).unwrap_or(false)
} Try / catch
match identifier { Some(id) if !id.is_empty() => ..., _ => Err(invalid_operation("relation.identifier is required")) } Prevention
- Always supply identifier when calling api.Relation.create
- Validate fixtures for unit tests include identifiers
- Avoid custom relation macros that drop identifier
When it happens
Trigger: Calling get_temp_relation_path with a relation whose `identifier` attribute is missing, None, an empty string, or not a string (e.g. a relation object built without an identifier, or attribute shadowed by a custom relation macro).
Common situations: Custom relation macros returning partially-built relations; unit-test fixtures constructing relations without identifiers; batch/incremental processing where an intermediate relation lost its identifier.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- get_temp_relation_path: relation.database is required
- {} relation creation from Jinja values
- Unknown method on BaseRelationObject: '{name}'
- Unknown method on StaticBaseRelationObject: '{name}'
- Failed to convert quoting to resolved quoting
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/6d9eb618dcfd4584.
Report an issue: GitHub.