{"record":{"id":"aa25859d237fc4f2","repo":"facebook/flow","slug":"failed-to-get-current-directory","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/ast_command.rs","lineNumber":287,"sourceCode":"        None\n    } else {\n        Some(&mut token_sink as &mut dyn FnMut(flow_parser::TokenSinkResult))\n    };\n\n    // Make the parser as permissive as possible.\n    // TODO: make these CLI flags\n    let parse_options = Some(ParseOptions {\n        components: !no_component_syntax,\n        enums: !no_enums,\n        use_strict,\n        ..PERMISSIVE_PARSE_OPTIONS\n    });\n\n    let filename = file.path_of_file_input().map(str::to_owned);\n    let filename = if use_relative_path {\n        filename.as_ref().map(|filename| {\n            flow_common::files::relative_path(\n                &std::env::current_dir().expect(\"failed to get current directory\"),\n                filename,\n            )\n        })\n    } else {\n        filename\n    };\n\n    let (ast, errors) = match file_type {\n        AstFileType::FileJs => {\n            // flow ast is a standalone parser - use the raw constructor\n            // so paths are stored as-is without root stripping.\n            let filekey = filename\n                .clone()\n                .map(|filename| FileKey::new(FileKeyInner::SourceFile(filename)));\n            let (ocaml_ast, errors) = match filekey.clone() {\n                Some(filekey) => flow_parser::parse_program_file::<()>(\n                    false,\n                    token_sink,","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/ast_command.rs#L269-L305","documentation":"For relative-path output, `flow ast` calls std::env::current_dir() and .expect(\"failed to get current directory\") — failure panics the command. On Unix the canonical cause is that the process's working directory was deleted (or its permissions revoked) after the shell/tool started: getcwd() then fails with ENOENT because the path to the cwd no longer resolves.","triggerScenarios":"Invoking flow ast with relative-path output from a shell, editor, or daemon whose cwd was deleted after it started — another terminal rm -rf of a build dir, a clean step removing the checkout, container layer removal.","commonSituations":"A terminal left sitting in a removed build/output directory; scripts that cd into temp dirs later cleaned by another job; CI steps running after the workspace directory was wiped; editors launched from a since-deleted directory.","solutions":["cd into an existing directory and rerun the command.","Recreate the deleted directory, or restart the shell/editor/daemon so it picks up a valid cwd.","In scripts and long-running tools, avoid anchoring to directories that other jobs delete."],"exampleFix":"# before: shell still sits in a directory that was deleted\ncd /tmp/gone-build && flow ast --filename x.js   # panics: failed to get current directory\n\n# after: move to a live directory first\ncd \"$HOME\" && flow ast --filename /real/path/x.js","handlingStrategy":"validation","validationCode":"# Run before invoking Flow from a possibly-stale shell or daemon.\npwd >/dev/null 2>&1 || echo \"cwd is gone: cd to an existing directory first\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["cd to a stable directory before invoking the CLI in scripts.","Restart shells/editors/daemons after their working directory is deleted.","Do not anchor long-running tools to build output dirs that other jobs clean."],"tags":["cli","cwd","environment","panic","rust"],"backgroundTag":"current-directory-deleted","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}