dbt-labs/dbt-core · error
name_span is required
Error message
name_span is required
What it means
Sibling of the span assertion: building `MacroInfo` panics with `inner_macro.macro_name_span.expect("name_span is required")` when the macro's name span (the byte range of the macro's name in its source file) is `None`. The name span is required for macro resolution diagnostics and docs; the library treats its absence as a broken parse result.
Source
Thrown at crates/dbt-schemas/src/schemas/macros.rs:123
project_root: &Path,
) -> BTreeMap<String, Vec<MacroUnit>> {
let mut macros = BTreeMap::new();
for (_, inner_macro) in nodes.iter() {
let display_path = inner_macro
.get_node_path(NodePathKind::Definition, project_root, project_root)
.into_owned();
macros
.entry(inner_macro.package_name.clone())
.or_insert(vec![])
.push(MacroUnit {
info: MacroInfo {
name: inner_macro.name.clone(),
path: display_path,
span: inner_macro.span.expect("span is required"),
funcsign: inner_macro.funcsign.clone(),
args: inner_macro.args.clone(),
unique_id: inner_macro.unique_id.clone(),
name_span: inner_macro.macro_name_span.expect("name_span is required"),
},
sql: inner_macro.macro_sql.clone(),
});
}
macros
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_macro_config_default_serializes_docs_with_nulls() {
// serialize_docs_with_nulls forces both fields to be present, including
// node_color (normally Option-skipped) as an explicit null.
let config = MacroConfig::default();
let json = serde_json::to_value(&config).expect("serializes");
let docs = json.get("docs").expect("docs key present");View on GitHub (pinned to 0267ce9170)
Solutions
- Parse macros through the standard parser path so `macro_name_span` is populated from the source text
- Regenerate serialized macro artifacts with the matching dbt version
- Set `macro_name_span` explicitly when constructing `InnerMacro` in tooling/tests
Example fix
// before
name_span: inner_macro.macro_name_span.expect("name_span is required"),
// after
name_span: inner_macro.macro_name_span.unwrap_or_default(), Defensive patterns
Strategy: validation
Validate before calling
// before manifest aggregation
if inner_macro.macro_name_span.is_none() {
return Err(/* error: macro {} missing name_span; re-parse */);
} Type guard
fn has_name_span(m: &InnerMacro) -> bool { m.macro_name_span.is_some() } Try / catch
let result = std::panic::catch_unwind(|| build_macros(resolver_state));
Prevention
- Never build InnerMacro by hand in tests without setting both span and macro_name_span
- Pin artifact schema versions when caching parsed macros
- Fail at parse time (not aggregation time) if a name span cannot be extracted
When it happens
Trigger: Aggregating macros into the manifest with an `InnerMacro` whose `macro_name_span: Option<Span>` is `None` — same causes as the span assertion: partially-deserialized macros, artifact version mismatch, or programmatic construction that skipped name-span extraction.
Common situations: Loading macros from a cached/partial parse artifact that omitted `macro_name_span`; custom code paths or tests that construct macros without recording the name span.
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
- span is required
- root manifest path config missing
- manifest path config missing for manifest node package
- DbtQuoting should be set
- Unknown or unsupported adapter type
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/9e304283675b5a68.
Report an issue: GitHub.