{"record":{"id":"e3a716a6c5b230c8","repo":"facebook/flow","slug":"file-key-project-root-has-not-been-set","errorCode":null,"errorMessage":"File_key: project_root has not been set","messagePattern":"File_key: project_root has not been set","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_parser/src/file_key.rs","lineNumber":186,"sourceCode":"}\n\npub fn set_project_root(root: &str) {\n    *PROJECT_ROOT.write().unwrap() = Some(enforce_trailing_slash(root));\n}\n\npub fn set_flowlib_root(root: &str) {\n    *FLOWLIB_ROOT.write().unwrap() = Some(enforce_trailing_slash(root));\n}\n\n// Retrieve a root, crashing immediately if not set. Following Hack's\n// Relative_path convention: an unset root is a programmer error that\n// should be caught at the call site, not masked downstream.\npub fn get_project_root() -> String {\n    PROJECT_ROOT\n        .read()\n        .unwrap()\n        .clone()\n        .expect(\"File_key: project_root has not been set\")\n}\n\npub fn get_flowlib_root() -> String {\n    FLOWLIB_ROOT\n        .read()\n        .unwrap()\n        .clone()\n        .expect(\"File_key: flowlib_root has not been set\")\n}\n\nfn is_relative(path: &str) -> bool {\n    std::path::Path::new(path).is_relative()\n}\n\n// libs, then source and json files at the same priority since JSON files are\n// basically source files. We don't actually read resource files so they come\n// last\nfn order_of_inner(inner: &FileKeyInner) -> i32 {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_parser/src/file_key.rs#L168-L204","documentation":"file_key keeps the project root in a process-global RwLock<Option<String>>; get_project_root panics via expect on None when set_project_root was never called. The comment states this is deliberate, following Hack's Relative_path convention: an unset root is a programmer error to crash on at the call site, not mask downstream. FileKey construction and path relativization all route through this getter.","triggerScenarios":"A new binary, example, or test constructs FileKeys (file_of, or any path<->FileKey conversion) before any set_project_root call; a library consumer of flow_parser forgets initialization; a test harness lacks the setup fixture other suites provide.","commonSituations":"Adding a fresh integration test or small utility binary against the parser crate; refactoring init out of main; spawning worker processes that skip the normal startup sequence.","solutions":["Call flow_parser::file_key::set_project_root at process start, before any FileKey use","Centralize initialization in one init function invoked from main() and every test harness setup","If embedding the crate, document set_project_root as a required first call"],"exampleFix":"// before — panics: root never set\nlet fk = FileKey::file_of(&source_path);\n\n// after — initialize roots once at startup\nfn init_roots(project_root: &Path, flowlib_root: &Path) {\n    flow_parser::file_key::set_project_root(&project_root.to_string_lossy());\n    flow_parser::file_key::set_flowlib_root(&flowlib_root.to_string_lossy());\n}\n// ...in main() / test setup, before any FileKey:\ninit_roots(&root, &flowlib);\nlet fk = FileKey::file_of(&source_path);","handlingStrategy":"validation","validationCode":"// One-time init before any FileKey use (main + every test harness)\npub fn init_file_keys(project_root: &str, flowlib_root: &str) {\n    flow_parser::file_key::set_project_root(project_root);\n    flow_parser::file_key::set_flowlib_root(flowlib_root);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call set_project_root first thing in every binary entry point and test setup fixture","Fail fast at boot: invoke get_project_root once with your own clear error message","When embedding flow_parser, document root initialization as a required first call"],"tags":["rust","global-state","initialization","programmer-error"],"backgroundTag":"uninitialized-global-state","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}