{"record":{"id":"37d9322233a2cbf9","repo":"Hmbown/CodeWhale","slug":"runtime-store-root-cannot-be-empty","errorCode":null,"errorMessage":"Runtime store root cannot be empty","messagePattern":"Runtime store root cannot be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":8857,"sourceCode":"        0\n    } else {\n        u64::try_from(millis).unwrap_or(u64::MAX)\n    }\n}\n\nfn panic_payload_message(payload: &(dyn std::any::Any + Send)) -> String {\n    if let Some(message) = payload.downcast_ref::<&str>() {\n        (*message).to_string()\n    } else if let Some(message) = payload.downcast_ref::<String>() {\n        message.clone()\n    } else {\n        \"unknown panic payload\".to_string()\n    }\n}\n\nfn checked_runtime_store_root(root: PathBuf) -> Result<PathBuf> {\n    if root.as_os_str().is_empty() {\n        bail!(\"Runtime store root cannot be empty\");\n    }\n    if root\n        .components()\n        .any(|component| matches!(component, Component::ParentDir))\n    {\n        bail!(\"Runtime store root cannot contain '..' components\");\n    }\n    let absolute = if root.is_absolute() {\n        root\n    } else {\n        std::env::current_dir()\n            .context(\"failed to resolve current directory for runtime store\")?\n            .join(root)\n    };\n    match absolute.canonicalize() {\n        Ok(path) => Ok(path),\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => {\n            Ok(normalize_path_components(&absolute))","sourceCodeStart":8839,"sourceCodeEnd":8875,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/runtime_threads.rs#L8839-L8875","documentation":"checked_runtime_store_root validates the runtime store root before any filesystem use and rejects an empty path (crates/tui/src/runtime_threads.rs:8857). An empty root would resolve to ambiguous relative locations and corrupt store layout, so the constructor fails fast.","triggerScenarios":"An env var for the store root set but empty (VAR= with nothing after); a config default missing after an upgrade so \"\" propagates; code passing PathBuf::from(\"\") or PathBuf::new() when a lookup fails","commonSituations":"Dotfiles exporting empty env vars; CI templates that define the variable without a value; refactors that default to an empty string instead of a real path; fresh machines without the configured directory.","solutions":["Set an explicit non-empty store root path in config/environment","Treat an empty env var as unset and fall back to the documented default location","Validate the resolved path at startup before constructing the runtime","Use an absolute path to avoid dependence on the process working directory"],"exampleFix":"// before\nlet root = PathBuf::from(std::env::var(\\\"CODEWHALE_STORE_ROOT\\\").unwrap_or_default());\n\n// after\nlet root = std::env::var(\"CODEWHALE_STORE_ROOT\")\n    .ok()\n    .filter(|v| !v.trim().is_empty())               // empty means unset\n    .map(PathBuf::from)\n    .unwrap_or_else(|| default_store_root());","handlingStrategy":"validation","validationCode":"// Validate before constructing the runtime.\nlet raw = std::env::var(\"CODEWHALE_STORE_ROOT\").ok()\n    .filter(|v| !v.trim().is_empty());\nlet root: PathBuf = raw.map(PathBuf::from)\n    .unwrap_or_else(default_store_root);\nassert!(!root.as_os_str().is_empty(), \"store root must not be empty\");","typeGuard":"fn is_nonempty_root(root: &Path) -> bool {\n    !root.as_os_str().is_empty()\n}","tryCatchPattern":"match RuntimeStore::open(root) {\n    Ok(store) => store,\n    Err(err) if err.to_string().contains(\"store root cannot be empty\") => {\n        RuntimeStore::open(default_store_root()).expect(\"default store root must be valid\")\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Filter empty env values to 'unset' at config load time","Always configure an explicit fallback/default store location","Smoke-test configuration parsing in CI with empty-variable cases","Never build store paths from unvalidated user-supplied strings"],"tags":["rust","configuration","filesystem","store","startup"],"backgroundTag":"empty-configuration-path","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}