{"record":{"id":"0ff973e6f03307fa","repo":"Hmbown/CodeWhale","slug":"project-workspace-path-cannot-be-empty","errorCode":null,"errorMessage":"project workspace path cannot be empty","messagePattern":"project workspace path cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/lib.rs","lineNumber":6798,"sourceCode":"        .parent()\n        .context(\"config path must include a parent directory\")?;\n    let parent = match parent.canonicalize() {\n        Ok(parent) => parent,\n        Err(err) if err.kind() == std::io::ErrorKind::NotFound => parent.to_path_buf(),\n        Err(err) => {\n            return Err(err).with_context(|| {\n                format!(\"failed to resolve config directory {}\", parent.display())\n            });\n        }\n    };\n    let normalized = parent.join(file_name);\n    reject_path_symlink(&normalized)?;\n    Ok(normalized)\n}\n\nfn normalize_project_workspace(workspace: &Path) -> Result<PathBuf> {\n    if workspace.as_os_str().is_empty() {\n        bail!(\"project workspace path cannot be empty\");\n    }\n    if workspace\n        .components()\n        .any(|component| matches!(component, Component::ParentDir))\n    {\n        bail!(\"project workspace path cannot contain '..' components\");\n    }\n    let absolute = if workspace.is_absolute() {\n        workspace.to_path_buf()\n    } else {\n        std::env::current_dir()\n            .context(\"failed to resolve current directory for project workspace\")?\n            .join(workspace)\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":6780,"sourceCodeEnd":6816,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/lib.rs#L6780-L6816","documentation":"normalize_project_workspace validates the project workspace directory path the same way the config path is validated. An empty path cannot name a workspace directory, so it is rejected up front. The workspace is where project state is rooted, so a silent default would hide a real misconfiguration.","triggerScenarios":"Calling the workspace-setting/config API with an empty PathBuf, an env var holding \"\", or a workspace argument derived from an unset CLI flag.","commonSituations":"Running from a context where the workspace was expected to be auto-detected but was left empty, CI jobs missing the workspace input, or config files with an empty workspace value.","solutions":["Pass the absolute path of the project workspace directory","Fix the env var / CLI flag / config key that is empty","Let the tool auto-detect the workspace instead of supplying an empty value"],"exampleFix":"// before\nset_workspace(PathBuf::from(\"\"))\n// after\nset_workspace(PathBuf::from(\"/home/user/projects/myapp\"))","handlingStrategy":"validation","validationCode":"fn usable_workspace(p: &std::path::Path) -> bool {\n    !p.as_os_str().is_empty()\n}","typeGuard":"fn non_empty_workspace(p: Option<&str>) -> Option<std::path::PathBuf> {\n    p.filter(|s| !s.trim().is_empty()).map(std::path::PathBuf::from)\n}","tryCatchPattern":"match normalize_project_workspace(&workspace) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"workspace path cannot be empty\") => {\n        eprintln!(\"workspace not set; run from the project root or pass --workspace\");\n        std::process::exit(2);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Fail CI jobs fast when the workspace input is empty","Prefer auto-detection over passing an empty value","Validate workspace env vars at script start"],"tags":["config","path","workspace","validation"],"backgroundTag":"empty-required-field","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}