gleam-lang/gleam · error

Directory name

Error message

Directory name

What it means

During `gleam export erlang-shipment`, the code iterates build-directory entries, and for each directory calls path.file_name().expect("Directory name"). file_name() returns None only for paths ending in '..' or the filesystem root, so this panics if a directory entry in build/packages has no final path component.

Solutions

  1. Delete the build directory and re-run `gleam build` before `gleam export erlang-shipment`
  2. Check for symlinks or mounts inside build/ that produce root-like paths and replace them with real directories
  3. Run the export from the project root with default paths so the build directory layout is standard
  4. Report to the Gleam repo — the code should skip unnamed entries instead of panicking
Defensive patterns

Strategy: validation

Validate before calling

// Validate build tree before export
for entry in fs::read_dir("build/packages")? {
    let p = entry?.path();
    if p.is_dir() && p.file_name().is_none() {
        return Err("corrupt build directory entry; delete build/ and rebuild".into());
    }
}

Prevention

When it happens

Trigger: Exporting an Erlang shipment when a package subdirectory path under the build directory resolves to a path with no file_name — practically caused by unusual symlinks, a directory literally at a root-like path, or a corrupted build tree.

Common situations: Symlinked or bind-mounted build directories on unusual filesystems; corrupted build output after interrupted builds; running the export with a redirected build path pointing at an odd location.

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 gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/3f4c3ccb7f306697. Report an issue: GitHub.

Appendix: source

Thrown at compiler-cli/src/export.rs:164

            codegen: Codegen::All,
            compile: Compile::All,
            mode,
            target: Some(target),
            no_print_progress: false,
            erlang_output: ErlangOutput::Binary,
        },
        crate::build::download_dependencies(paths, crate::cli::Reporter::new())?,
    )?;

    for entry in fs::read_dir(&build)?.filter_map(Result::ok) {
        let path = entry.path();

        // We are only interested in package directories
        if !path.is_dir() {
            continue;
        }

        let name = path.file_name().expect("Directory name");
        let build = build.join(name);
        let out = out.join(name);
        fs::mkdir(&out)?;

        // Copy desired package subdirectories
        for subdirectory in ["ebin", "priv", "include"] {
            let source = build.join(subdirectory);
            if source.is_dir() {
                let source = fs::canonicalise(&source)?;
                let out = out.join(subdirectory);
                fs::copy_dir(source, &out)?;
            }
        }
    }

    // PowerShell entry point script.
    write_entrypoint_script(
        &out.join(ENTRYPOINT_FILENAME_POWERSHELL),

View on GitHub (pinned to 15b07c7830)