dbt-labs/dbt-core · error

File name can't be empty

Error message

File name can't be empty

What it means

Panic "File name can't be empty" is raised in resolve_minimal_properties when `dbt_asset.path.file_stem()` returns None. file_stem returns None only for paths that terminate in `..` or are empty, so this guards the assumption that every asset being resolved has a real file name.

Source

Thrown at crates/dbt-parser/src/resolve/resolve_properties.rs:671

            init_project_config(
                &package.dbt_project.semantic_models,
                (),
                Some(package.dbt_project.name.as_str()),
                disallow_plus_prefix_from_flags(root_package.dbt_project.flags.as_ref()),
                adapter_type,
            )
        },
        adapter_type,
    )?;

    for dbt_asset in package.dbt_properties.iter().dedup() {
        token.check_cancellation()?;
        let absolute_path = dbt_asset.base_path.join(&dbt_asset.path);
        let display_path = dbt_asset.to_display_path(&arg.io.in_dir);
        let asset_name = dbt_asset
            .path
            .file_stem()
            .expect("File name can't be empty")
            .to_string_lossy();
        let span = create_debug_span(AssetParsed::new_with_phase_from_context(
            package.dbt_project.name.clone(),
            asset_name.to_string(),
            dbt_asset.path.display().to_string(),
            display_path.display().to_string(),
            None,
        ));

        let dependency_package_name = if package.dbt_project.name != root_package_name {
            Some(package.dbt_project.name.as_str())
        } else {
            None
        };

        {
            let _guard = span.enter();
            let input = try_read_yml_to_str(&absolute_path)?;

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Skip assets whose path.file_stem() is None (continue) instead of panicking.
  2. Validate/filter asset paths during the directory walk to reject empty or `..`-terminated paths.
  3. Check how dbt_asset.path is constructed (base_path.join) for accidental empty components.

Example fix

// before
let asset_name = dbt_asset.path.file_stem().expect("File name can't be empty").to_string_lossy();
// after
let asset_name = match dbt_asset.path.file_stem() {
    Some(stem) => stem.to_string_lossy(),
    None => continue,
};
Defensive patterns

Strategy: validation

Validate before calling

// pre-check asset paths before resolution
for asset in &assets {
    assert!(!asset.path.as_os_str().is_empty() && asset.path.file_stem().is_some(), "bad asset path {:?}", asset.path);
}

Type guard

fn has_file_stem(p: &Path) -> bool { p.file_stem().is_some() }

Prevention

When it happens

Trigger: An asset whose path is empty or ends with a parent-directory component (e.g., path=".." or "") reaches resolve_minimal_properties via the asset walk.

Common situations: A malformed glob or symlink/`..` entry slipping into the property-file walk; passing an in_dir whose traversal yields a root-only path; path constructed by joining an empty string.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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