{"record":{"id":"a42c698caaa8d6ba","repo":"AlexsJones/llmfit","slug":"invalid-dir-entry","errorCode":null,"errorMessage":"invalid dir entry","messagePattern":"invalid dir entry","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"llmfit-tui/build.rs","lineNumber":37,"sourceCode":"        for file in &files {\n            println!(\"cargo:rerun-if-changed={}\", file.display());\n        }\n        generate_assets_from_dist(&dist_dir, &files)\n    } else {\n        println!(\n            \"cargo:warning=llmfit-web/dist not found. Falling back to placeholder embedded dashboard. Run `npm ci && npm run build` in llmfit-web.\"\n        );\n        generate_fallback_assets()\n    };\n\n    fs::write(&out_file, generated).expect(\"failed to write generated web_assets.rs\");\n}\n\nfn collect_files(dir: &Path, files: &mut Vec<PathBuf>) {\n    let entries = fs::read_dir(dir).unwrap_or_else(|_| panic!(\"failed to read {}\", dir.display()));\n\n    for entry in entries {\n        let entry = entry.expect(\"invalid dir entry\");\n        let path = entry.path();\n        if path.is_dir() {\n            collect_files(&path, files);\n        } else {\n            files.push(path);\n        }\n    }\n}\n\nfn generate_assets_from_dist(dist_dir: &Path, files: &[PathBuf]) -> String {\n    let mut output = String::new();\n    output.push_str(\"#[derive(Clone, Copy)]\\n\");\n    output.push_str(\"pub(crate) struct EmbeddedAsset {\\n\");\n    output.push_str(\"    pub(crate) path: &'static str,\\n\");\n    output.push_str(\"    pub(crate) content_type: &'static str,\\n\");\n    output.push_str(\"    pub(crate) bytes: &'static [u8],\\n\");\n    output.push_str(\"}\\n\\n\");\n    output.push_str(\"pub(crate) static EMBEDDED_WEB_ASSETS: &[EmbeddedAsset] = &[\\n\");","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/AlexsJones/llmfit/blob/acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe/llmfit-tui/build.rs#L19-L55","documentation":"Inside collect_files(), which recursively walks llmfit-web/dist to enumerate dashboard assets, each DirEntry from fs::read_dir is unwrapped with .expect(\"invalid dir entry\"). Iteration errors occur when an entry cannot be read — the file was deleted or renamed between the directory listing and the entry read (a race with `npm run build` rewriting dist/), or a subdirectory became unreadable due to permissions.","triggerScenarios":"Running `cargo build` in llmfit-tui while `npm run build` in llmfit-web is concurrently rewriting dist/ (files vanish mid-walk); a permissions change on a dist subdirectory during the walk; network filesystem flakiness where dist lives on a mount.","commonSituations":"Dev loops that rebuild the web dashboard and the Rust crate in parallel (npm watch + cargo watch); CI jobs sharing a workspace where one step regenerates dist while another compiles; NFS/FUSE-mounted checkouts.","solutions":["Re-run `cargo build -p llmfit` after the npm build finishes — the rerun-if-changed directives will pick up the new dist and the walk will succeed","Sequence your tooling so dist/ is fully built before the cargo step (make the cargo step depend on the npm build step)","If it recurs, check permissions on llmfit-web/dist subdirectories (`find llmfit-web/dist -type d ! -readable`)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# shell pre-flight: snapshot dist so the cargo walk sees a stable tree\nnpm --prefix llmfit-web ci && npm --prefix llmfit-web run build\ntar -C llmfit-web -cf /tmp/llmfit-dist.tar dist  # stable copy for rebuilds","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Finish `npm run build` in llmfit-web before starting `cargo build -p llmfit`","Avoid npm watch/cargo watch pointing at the same dist simultaneously","If dist is on NFS/FUSE, copy it locally before building the Rust crate"],"tags":["rust","build-script","filesystem","race-condition","panic"],"backgroundTag":"directory-read-failed","analyzedSha":"acc7e40c3a0afbd36510a92f2f8f3d5177cfc0fe","analyzedAt":"2026-08-17T10:35:29.658Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}