Hmbown/CodeWhale · error · anyhow::Error

config path cannot be empty

Error message

config path cannot be empty

What it means

Thrown by normalize_config_file_path when the config path is the empty string. The normalizer validates shape (non-empty, no '..', has a file name) before resolving the path, and an empty path fails the first check rather than being treated as 'use the default location'.

Source

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

                    child_key.clone()
                } else {
                    format!("{key}.{child_key}")
                };
                redacted.insert(
                    child_key.clone(),
                    redact_toml_value_for_display_inner(&path, sensitive, child_value),
                );
            }
            toml::Value::Table(redacted)
        }
        _ if sensitive => toml::Value::String("********".to_string()),
        _ => value.clone(),
    }
}

fn normalize_config_file_path(path: PathBuf) -> Result<PathBuf> {
    if path.as_os_str().is_empty() {
        bail!("config path cannot be empty");
    }
    if path
        .components()
        .any(|component| matches!(component, Component::ParentDir))
    {
        bail!("config path cannot contain '..' components");
    }
    if path.file_name().is_none() {
        bail!("config path must include a file name");
    }
    let absolute = if path.is_absolute() {
        path
    } else {
        std::env::current_dir()
            .context("failed to resolve current directory for config path")?
            .join(path)
    };
    let file_name = absolute

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Omit the --config flag entirely to use default config discovery instead of passing an empty string
  2. Fix the source variable so it holds a real path: CFG="${CFG:-$HOME/.codewhale/codewhale.toml}"
  3. In code, only call the API when the path is present: map the Option to Result with a clear 'config path required' message

Example fix

// before
let path = normalize_config_file_path(PathBuf::from(cfg_flag.unwrap_or_default()))?;

// after
let path = normalize_config_file_path(PathBuf::from(cfg_flag.context("config path required")?))?;
Defensive patterns

Strategy: validation

Validate before calling

if let Some(cfg) = &cfg_flag {
    anyhow::ensure!(!cfg.is_empty(), "config path must not be empty");
    let normalized = normalize_config_file_path(PathBuf::from(cfg))?;
    // use normalized
} else {
    // default discovery path
}

Try / catch

let path = match normalize_config_file_path(candidate) {
    Ok(p) => p,
    Err(err) if err.to_string().contains("config path cannot be empty") => {
        anyhow::bail!("no config path given; pass --config <file> or omit the flag");
    }
    Err(err) => return Err(err),
};

Prevention

When it happens

Trigger: Passing an explicitly empty --config argument, e.g. `--config ""`, or building the path from an empty variable/Option default (PathBuf::from(opt.unwrap_or_default())) so the empty value reaches the normalizer instead of falling back to discovery.

Common situations: Shell scripts passing `--config $CFG` with CFG unset or empty; CI matrices where one axis leaves the config var blank; programmatic callers converting an Option<String> into "" instead of skipping the override.

Related errors


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