{"record":{"id":"eda434b8047ff1a5","repo":"gleam-lang/gleam","slug":"is-gleam-path-strip-prefix","errorCode":null,"errorMessage":"is_gleam_path(): strip_prefix","messagePattern":"is_gleam_path\\(\\): strip_prefix","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-cli/src/fs.rs","lineNumber":441,"sourceCode":"            err: Some(error.to_string()),\n        })\n}\n\nstatic IS_GLEAM_PATH_PATTERN: OnceLock<Regex> = OnceLock::new();\n\nfn is_gleam_path(path: &Utf8Path, dir: impl AsRef<Utf8Path>) -> bool {\n    IS_GLEAM_PATH_PATTERN\n        .get_or_init(|| {\n            Regex::new(&format!(\n                \"^({module}{slash})*{module}\\\\.gleam$\",\n                module = \"[a-z][_a-z0-9]*\",\n                slash = \"(/|\\\\\\\\)\",\n            ))\n            .expect(\"is_gleam_path() RE regex\")\n        })\n        .is_match(\n            path.strip_prefix(dir.as_ref())\n                .expect(\"is_gleam_path(): strip_prefix\")\n                .as_str(),\n        )\n}\n\nfn is_gleam_build_dir(e: &ignore::DirEntry) -> bool {\n    if !e.path().is_dir() || !e.path().ends_with(\"build\") {\n        return false;\n    }\n\n    let Some(parent_path) = e.path().parent() else {\n        return false;\n    };\n\n    parent_path.join(\"gleam.toml\").exists()\n}\n\n/// Walks through all Gleam module files in the directory, even if ignored,\n/// except for those in the `build/` directory. Excludes any Gleam files within","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-cli/src/fs.rs#L423-L459","documentation":"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.","triggerScenarios":"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.","commonSituations":"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:\\).","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."],"exampleFix":"// before\nlet files: Vec<_> = gleam_files(&Utf8Path::new(\"src\")).collect();\n// after\nlet dir = Utf8PathBuf::from_path_buf(\n    std::fs::canonicalize(\"src\").expect(\"canonicalise src\"),\n)\n.expect(\"utf-8\");\nlet files: Vec<_> = gleam_files(&dir).collect();","handlingStrategy":"validation","validationCode":"// canonicalise and verify containment before scanning\nlet dir = Utf8PathBuf::from_path_buf(dir.canonicalize()?).map_err(|_| anyhow!(\"non-utf8 dir\"))?;\nassert!(Path::new(\"src/lib.gleam\").starts_with(&dir), \"source dirs must live under dir\");","typeGuard":"fn is_under(dir: &Utf8Path, p: &Path) -> bool { p.strip_prefix(dir).is_ok() }","tryCatchPattern":"std::panic::catch_unwind(|| gleam_files(&dir).collect::<Vec<_>>())\n    .map_err(|_| anyhow!(\"path root mismatch while scanning gleam files\"))?","preventionTips":["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."],"tags":["filesystem","path","panic","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}