{"record":{"id":"5871aa7b93f2b50c","repo":"facebook/flow","slug":"failed-to-get-current-directory-5871aa","errorCode":null,"errorMessage":"failed to get current directory","messagePattern":"failed to get current directory","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_cli/src/command_utils.rs","lineNumber":120,"sourceCode":"                    Box::new(move |path: &str| flow_common::files::is_valid_path(&opts, path))\n                }\n                None => Box::new(|path: &str| path.ends_with(\".js\")),\n            };\n            let root = paths[0].clone();\n            let others = paths[1..].to_vec();\n            Box::new(flow_utils_find::make_next_files(filter, others, root))\n        }\n    };\n    flow_common::files::get_all(&mut *next_files)\n}\n\npub(super) fn get_filenames_from_input(\n    allow_imaginary: bool,\n    input_file: Option<&str>,\n    filenames: Option<&[String]>,\n) -> Vec<String> {\n    let cwd = std::env::current_dir()\n        .expect(\"failed to get current directory\")\n        .to_string_lossy()\n        .to_string();\n    let handle_imaginary = |filename: &str| -> String {\n        if allow_imaginary {\n            flow_common::files::imaginary_realpath(filename)\n        } else {\n            let msg = format!(\"File not found: {:?}\", filename);\n            flow_common_exit::exit(FlowExitStatus::NoInput, Some(&msg));\n        }\n    };\n    let input_file_filenames = match input_file {\n        Some(\"-\") => {\n            let stdin = std::io::stdin();\n            let lines: Vec<String> = stdin\n                .lock()\n                .lines()\n                .map(|l| l.expect(\"failed to read stdin\"))\n                .collect();","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/command_utils.rs#L102-L138","documentation":"get_filenames_from_input builds the list of files to check (from --input-file/-, CLI filename args, or the find-based walker) and resolves every relative name against std::env::current_dir(). That syscall fails with ENOENT when the directory the process was started in has been unlinked, or EACCES when execute permission on it was stripped; the .expect() then panics before any file is processed.","triggerScenarios":"The shell's cwd (a temp dir, deleted checkout, or removed build dir) is rm -rf'd while a flow invocation is running or about to resolve paths; permissions on the cwd are revoked mid-run; container/sandbox unmounts the cwd.","commonSituations":"CI ephemeral workspaces cleaned by a concurrent step; scripts that `cd \"$(mktemp -d)\"` and clean up too early; long-running editors/tasks started from a directory later deleted; Docker volume unmounted underneath the process.","solutions":["Run the command again from a directory that exists (`cd /` or re-enter the repo), or recreate the deleted workspace","Fix script ordering so cleanup (rm -rf of temp/workspace dirs) runs strictly after the flow command exits (use trap/finally)","Pass absolute file paths and an explicit --root so resolution never depends on a live cwd","Maintainer: replace the expect with a graceful exit (FlowExitStatus::InputError plus a message) when current_dir errs"],"exampleFix":"// before\nlet cwd = std::env::current_dir()\n    .expect(\"failed to get current directory\")\n    .to_string_lossy()\n    .to_string();\n\n// after\nlet cwd = match std::env::current_dir() {\n    Ok(dir) => dir.to_string_lossy().to_string(),\n    Err(e) => flow_common_exit::exit(\n        FlowExitStatus::InputError,\n        Some(&format!(\"cannot resolve current directory: {e}\")),\n    ),\n};","handlingStrategy":"validation","validationCode":"// Rust: verify cwd is resolvable before invoking the CLI\nif std::env::current_dir().is_err() {\n    eprintln!(\"cwd is gone; cd to an existing directory first\");\n    std::process::exit(1);\n}\n\n# Shell wrapper: a deleted cwd makes `cd .` fail\nbash -c 'cd . 2>/dev/null || { echo \"cwd deleted\"; exit 1; }; exec flow \"$@\"' _ check-contents file.js","typeGuard":null,"tryCatchPattern":"let cwd = match std::env::current_dir() {\n    Ok(dir) => dir.to_string_lossy().to_string(),\n    Err(e) => flow_common_exit::exit(\n        FlowExitStatus::InputError,\n        Some(&format!(\"cannot resolve current directory: {e}\")),\n    ),\n};","preventionTips":["Run long-lived checks from stable directories (repo root), not temp dirs other steps may delete","Sequence CI cleanup strictly after tool exit (trap/finally), never in parallel with the check","Pass absolute paths and an explicit --root so path resolution never depends on a live cwd"],"tags":["rust","flow-cli","filesystem","cwd","enoent","panic"],"backgroundTag":"current-directory-deleted","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T11:17:13.642Z"}