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

  1. Parse macros through the standard parser path so `macro_name_span` is populated from the source text
  2. Regenerate serialized macro artifacts with the matching dbt version
  3. 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

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


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/9e304283675b5a68. Report an issue: GitHub.