Hmbown/CodeWhale · error · anyhow::Error

project workspace path cannot be empty

Error message

project workspace path cannot be empty

What it means

Thrown by normalize_project_workspace when the workspace path is the empty string. Like the config path normalizer, it validates shape before resolving: a workspace must be a non-empty path, and empty input is an error rather than a cue to use a default.

Source

Thrown at crates/config/src/lib.rs:6654

        .parent()
        .context("config path must include a parent directory")?;
    let parent = match parent.canonicalize() {
        Ok(parent) => parent,
        Err(err) if err.kind() == std::io::ErrorKind::NotFound => parent.to_path_buf(),
        Err(err) => {
            return Err(err).with_context(|| {
                format!("failed to resolve config directory {}", parent.display())
            });
        }
    };
    let normalized = parent.join(file_name);
    reject_path_symlink(&normalized)?;
    Ok(normalized)
}

fn normalize_project_workspace(workspace: &Path) -> Result<PathBuf> {
    if workspace.as_os_str().is_empty() {
        bail!("project workspace path cannot be empty");
    }
    if workspace
        .components()
        .any(|component| matches!(component, Component::ParentDir))
    {
        bail!("project workspace path cannot contain '..' components");
    }
    let absolute = if workspace.is_absolute() {
        workspace.to_path_buf()
    } else {
        std::env::current_dir()
            .context("failed to resolve current directory for project workspace")?
            .join(workspace)
    };
    match absolute.canonicalize() {
        Ok(path) => Ok(path),
        Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
            Ok(normalize_path_components(&absolute))

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Pass the actual project directory (absolute paths are safest): workspace = "/repo/my-project"
  2. Fix the empty variable: WORKSPACE="${WORKSPACE:-$PWD}"
  3. In code, require the workspace before calling the API instead of defaulting it to an empty path

Example fix

// before
let ws = normalize_project_workspace(Path::new(ws_flag.unwrap_or_default()))?;

// after
let ws = normalize_project_workspace(Path::new(ws_flag.context("workspace required")?))?;
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(!workspace.as_os_str().is_empty(), "workspace path required");
let normalized = normalize_project_workspace(&workspace)?;

Type guard

fn has_workspace(p: &std::path::Path) -> bool {
    !p.as_os_str().is_empty()
}

Prevention

When it happens

Trigger: Registering a lane/project with workspace set to "" — an empty CLI argument, an unset variable expanded to nothing, or an Option<PathBuf> defaulting to PathBuf::new() before reaching the normalizer.

Common situations: Automation where the workspace cell in a matrix is blank; wrapper scripts passing "$WORKSPACE" before it is assigned; code that converts a missing workspace into an empty PathBuf instead of requiring one.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/0ff973e6f03307fa. Report an issue: GitHub.