gleam-lang/gleam · error

Non Utf-8 Path

Error message

Non Utf-8 Path

What it means

A panic from `Utf8PathBuf::from_path_buf(path).expect("Non Utf-8 Path")` in `gleam_files`: the directory walk encountered a file whose name is not valid UTF-8, and the crate (like most of the Rust ecosystem) requires UTF-8 paths. Gleam module names are lowercase identifiers, so a non-UTF-8 filename can never be a valid module anyway.

Solutions

  1. Locate the offending file and rename it to a UTF-8 (ideally plain ASCII lowercase) name: `find src -print0 | grep -zP '[^\x00-\x7F]'` then `mv` it.
  2. Use `convmv -f latin1 -t utf-8 -r --notest src/` to batch-convert mis-encoded filenames.
  3. Move the non-UTF-8 file (e.g. data files) out of `src/`/`test/` — only Gleam modules belong there.
  4. On Linux, ensure the filesystem/locale is UTF-8 (`LANG=C.UTF-8`) so future files are created with valid names.

Example fix

// shell: find and fix the non-UTF-8 filename before running gleam
find src -print0 | grep -zP '[^\x00-\x7F]'
convmv -f latin1 -t utf-8 -r --notest src/
Defensive patterns

Strategy: validation

Validate before calling

// scan for non-UTF-8 filenames before invoking gleam
use std::ffi::OsStr;
fn all_utf8(dir: &Path) -> bool {
    walkdir::WalkDir::new(dir).into_iter().all(|e| {
        e.map(|e| e.file_name().to_str().is_some()).unwrap_or(true)
    })
}

Type guard

fn is_utf8_path(p: &std::path::Path) -> bool { p.to_str().is_some() }

Try / catch

std::panic::catch_unwind(|| gleam_files(&dir).collect::<Vec<_>>())
    .map_err(|_| anyhow!("project contains a non-UTF-8 filename"))?

Prevention

When it happens

Trigger: Running any gleam command that scans the project's source directories (`gleam build`, `gleam deps download`, etc.) when the `src/` or `test/` tree contains a file or directory with non-UTF-8 bytes in its name — typically a file created with a legacy locale encoding.

Common situations: Files created on Linux with a non-UTF-8 locale (e.g. ISO-8859-1 filenames), files extracted from an archive with mis-encoded names, editor/OS artifacts with exotic names, files copied from other filesystems (NFS/FAT) with byte-level names.

Related errors


AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/7e28c18da09a6548. Report an issue: GitHub.

Appendix: source

Thrown at compiler-cli/src/fs.rs:476

/// Walks through all Gleam module files in the directory, even if ignored,
/// except for those in the `build/` directory. Excludes any Gleam files within
/// invalid module paths, for example if they or a folder they're in contain a
/// dot or a hyphen within their names.
pub fn gleam_files(dir: &Utf8Path) -> impl Iterator<Item = Utf8PathBuf> + '_ {
    ignore::WalkBuilder::new(dir)
        .follow_links(true)
        .standard_filters(false)
        .filter_entry(|entry| !is_gleam_build_dir(entry))
        .build()
        .filter_map(Result::ok)
        .filter(|entry| {
            entry
                .file_type()
                .map(|type_| type_.is_file())
                .unwrap_or(false)
        })
        .map(ignore::DirEntry::into_path)
        .map(|path| Utf8PathBuf::from_path_buf(path).expect("Non Utf-8 Path"))
        .filter(move |d| is_gleam_path(d, dir))
}

/// Walks through all native files in the directory, such as `.mjs` and `.erl`,
/// even if ignored.
pub fn native_files(dir: &Utf8Path) -> impl Iterator<Item = Utf8PathBuf> + '_ {
    ignore::WalkBuilder::new(dir)
        .follow_links(true)
        .standard_filters(false)
        .filter_entry(|entry| !is_gleam_build_dir(entry))
        .build()
        .filter_map(Result::ok)
        .filter(|entry| {
            entry
                .file_type()
                .map(|type_| type_.is_file())
                .unwrap_or(false)
        })

View on GitHub (pinned to 15b07c7830)