gleam-lang/gleam · error
is_gleam_path(): strip_prefix
Error message
is_gleam_path(): strip_prefix
What it means
A panic from `path.strip_prefix(dir)` inside `is_gleam_path`: a directory entry produced by the walker does not start with the root `dir` being scanned, so the library cannot compute the module-relative path to match against the Gleam path regex. This indicates the walked paths and the configured root disagree.
Solutions
- Canonicalise the directory before scanning: `let dir = Utf8PathBuf::from_path_buf(dir.canonicalize().expect("dir"))?;` so walker entries and the root share one form.
- Use the same absolute, resolved path form consistently when constructing the project's src/test directory handles.
- Avoid symlinked source directories, or point `dir` at the symlink target instead.
- If it reproduces with plain absolute paths, file a bug upstream with the OS and exact `dir` value.
Example fix
// before
let files: Vec<_> = gleam_files(&Utf8Path::new("src")).collect();
// after
let dir = Utf8PathBuf::from_path_buf(
std::fs::canonicalize("src").expect("canonicalise src"),
)
.expect("utf-8");
let files: Vec<_> = gleam_files(&dir).collect(); Defensive patterns
Strategy: validation
Validate before calling
// canonicalise and verify containment before scanning
let dir = Utf8PathBuf::from_path_buf(dir.canonicalize()?).map_err(|_| anyhow!("non-utf8 dir"))?;
assert!(Path::new("src/lib.gleam").starts_with(&dir), "source dirs must live under dir"); Type guard
fn is_under(dir: &Utf8Path, p: &Path) -> bool { p.strip_prefix(dir).is_ok() } Try / catch
std::panic::catch_unwind(|| gleam_files(&dir).collect::<Vec<_>>())
.map_err(|_| anyhow!("path root mismatch while scanning gleam files"))? Prevention
- Always pass canonicalised absolute paths as the scan root.
- Avoid symlinked source directories, or resolve them before handing the path to gleam.
- On Windows, keep drive-letter casing consistent.
- Use the same path-construction helper everywhere so walker entries and roots always match.
When it happens
Trigger: Calling `gleam_files(dir)` where entries yielded by the `ignore::Walk` are not under `dir` — e.g. `dir` was passed with a different form (uncanonicalised, symlinked, or with different case/separator handling) than the paths the walker returns.
Common situations: Passing a path through a symlink so the walker resolves entries to the real path while `dir` remains the symlink path (or vice versa); passing a relative `dir` while entries come back absolute; Windows drive-letter casing mismatches (C:\ vs c:\).
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
- Non Utf8 Path
- Non-UTF8 path in hardlink_dir
- Source path should be under base
- archive entries
- archive entry
AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14).
Data as JSON: /api/errors/eda434b8047ff1a5.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-cli/src/fs.rs:441
err: Some(error.to_string()),
})
}
static IS_GLEAM_PATH_PATTERN: OnceLock<Regex> = OnceLock::new();
fn is_gleam_path(path: &Utf8Path, dir: impl AsRef<Utf8Path>) -> bool {
IS_GLEAM_PATH_PATTERN
.get_or_init(|| {
Regex::new(&format!(
"^({module}{slash})*{module}\\.gleam$",
module = "[a-z][_a-z0-9]*",
slash = "(/|\\\\)",
))
.expect("is_gleam_path() RE regex")
})
.is_match(
path.strip_prefix(dir.as_ref())
.expect("is_gleam_path(): strip_prefix")
.as_str(),
)
}
fn is_gleam_build_dir(e: &ignore::DirEntry) -> bool {
if !e.path().is_dir() || !e.path().ends_with("build") {
return false;
}
let Some(parent_path) = e.path().parent() else {
return false;
};
parent_path.join("gleam.toml").exists()
}
/// Walks through all Gleam module files in the directory, even if ignored,
/// except for those in the `build/` directory. Excludes any Gleam files withinView on GitHub (pinned to 15b07c7830)