{"record":{"id":"414322d67f050f42","repo":"facebook/flow","slug":"mkdir-no-fail","errorCode":null,"errorMessage":"mkdir_no_fail({:?}): {}","messagePattern":"mkdir_no_fail\\((.+?)\\): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_flowlib/src/lib.rs","lineNumber":98,"sourceCode":"        BuiltinLib::Flowlib => LibDir::Flowlib(path),\n        BuiltinLib::Prelude => LibDir::Prelude(path),\n        BuiltinLib::Tslib => LibDir::Tslib(path),\n    }\n}\n\npub fn path_of_libdir(libdir: &LibDir) -> &Path {\n    match libdir {\n        LibDir::Prelude(path) => path,\n        LibDir::Flowlib(path) => path,\n        LibDir::Tslib(path) => path,\n    }\n}\n\nfn mkdir(libdir: &LibDir) {\n    let path = path_of_libdir(libdir);\n    let parent_dir = path.parent().expect(\"libdir path should have a parent\");\n    sys_utils::mkdir_no_fail(parent_dir)\n        .unwrap_or_else(|e| panic!(\"mkdir_no_fail({:?}): {}\", parent_dir, e));\n    sys_utils::mkdir_no_fail(path).unwrap_or_else(|e| panic!(\"mkdir_no_fail({:?}): {}\", path, e));\n}\n\nfn write_flowlib(dir: &Path, (filename, contents): &(&str, &str)) {\n    let file = dir.join(filename);\n    fs::write(&file, contents).expect(\"failed to write flowlib file\");\n}\n\npub fn extract(libdir: &LibDir) {\n    mkdir(libdir);\n    let (path, lib) = match libdir {\n        LibDir::Prelude(path) => (path.as_path(), BuiltinLib::Prelude),\n        LibDir::Flowlib(path) => (path.as_path(), BuiltinLib::Flowlib),\n        LibDir::Tslib(path) => (path.as_path(), BuiltinLib::Tslib),\n    };\n    for entry in contents(lib) {\n        write_flowlib(path, entry);\n    }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_flowlib/src/lib.rs#L80-L116","documentation":"This panic fires inside flow_flowlib when extract() prepares the directory that will hold the extracted built-in libraries (Prelude, Flowlib, or Tslib, usually under the Flow temp dir). mkdir() first creates the PARENT of the libdir via sys_utils::mkdir_no_fail, and any failure is fatal: the process aborts with the offending parent directory in the message. extract() cannot proceed without this directory, so there is no fallback path.","triggerScenarios":"Calling flow_flowlib::extract(&LibDir::Prelude/Flowlib/Tslib(..)) (which server and CLI startup do) when the libdir's parent, e.g. <temp_dir>/flow/<hash>/, cannot be created: a path component has wrong permissions, a regular file exists where a directory is expected, the filesystem is read-only, or the temp dir was deleted concurrently.","commonSituations":"Containers or sandboxes where TMPDIR is read-only; running the daemon as a user that does not own the temp dir; leftover files left behind by a crashed earlier run at exactly the parent path; disk full; macOS seals or noexec mounts on the temp location.","solutions":["Inspect the directory printed in the panic message: stat each component of the path to find the one that is a file or has bad mode bits.","Fix it: chmod/chown the temp dir to the daemon user, or delete the stale file blocking the mkdir, then retry startup.","Point the temp dir somewhere writable (TMPDIR env or the temp_dir option in .flowconfig) and restart the server.","If the filesystem is read-only (container image), mount a writable tmpfs or choose a different temp_dir.","If the disk is full, free space and retry."],"exampleFix":"# before: temp_dir points into a read-only location\n[options]\ntemp_dir=/usr/share/flow-tmp\n\n# after: use a writable temp dir\n[options]\ntemp_dir=/tmp/flow","handlingStrategy":"validation","validationCode":"use std::{fs, io, path::Path};\n\nfn ensure_dir_writable(p: &Path) -> io::Result<()> {\n    fs::create_dir_all(p)?;\n    let probe = p.join(\".write-probe\");\n    fs::write(&probe, b\"\")?;\n    fs::remove_file(&probe)\n}\n\n// before calling flow_flowlib::extract(&libdir)\nensure_dir_writable(flow_flowlib::path_of_libdir(&libdir).parent().unwrap())?;","typeGuard":null,"tryCatchPattern":"let outcome = std::panic::catch_unwind(|| flow_flowlib::extract(&libdir));\nif outcome.is_err() {\n    // extraction aborted (mkdir failure); surface a normal error to the\n    // caller and point the user at temp-dir permissions instead of crashing\n    return Err(\"flowlib extraction failed; check temp-dir permissions\".into());\n}","preventionTips":["Keep the flow temp dir writable by the daemon user; verify once at service start with a write probe.","Clean stale flow temp dirs after crashes so leftover files never block the mkdir path.","Run the daemon under the same user that owns the temp dir.","Avoid read-only or noexec mounts for temp_dir in containers."],"tags":["filesystem","temp-dir","permissions","flowlib","mkdir","startup"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T06:17:17.905Z"}