Hmbown/CodeWhale · error · anyhow::Error
config path must include a file name
Error message
config path must include a file name
What it means
Thrown by normalize_config_file_path when path.file_name() is None — the path ends in a separator, is the filesystem root '/', or a Windows drive prefix like 'C:'. The normalizer requires the config path to designate a file, and such paths can only designate a directory (or nothing).
Source
Thrown at crates/config/src/lib.rs:6622
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
.file_name()
.map(OsString::from)
.context("config path must include a file name")?;
let parent = absolute
.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(),View on GitHub (pinned to 0c42157ee5)
Solutions
- Append the file name: ~/.config/codewhale/codewhale.toml instead of ~/.config/codewhale/
- Remove the trailing slash if you meant a file in the current directory (config.toml not config.toml/)
- In code, build the path with join("codewhale.toml") on the directory rather than passing the directory itself
Example fix
# before codewhale --config ~/.config/codewhale/ # after codewhale --config ~/.config/codewhale/codewhale.toml
Defensive patterns
Strategy: validation
Validate before calling
let p = Path::new(&flag); anyhow::ensure!(!p.as_os_str().is_empty(), "config path required"); anyhow::ensure!(p.file_name().is_some(), "config path must name a file, not a directory"); // safe to normalize now
Type guard
fn names_a_file(p: &std::path::Path) -> bool {
!p.as_os_str().is_empty() && p.file_name().is_some()
} Prevention
- Always build config paths as dir.join("codewhale.toml"), never pass the directory alone
- Strip trailing separators from user input before treating it as a file path
When it happens
Trigger: `--config /` or `--config ~/.config/codewhale/` (trailing slash on a directory); passing the config directory when the file path was intended.
Common situations: Scripts that join a directory variable and forget the file name; users pointing at the folder that contains codewhale.toml rather than the file; a path template whose '/{file}' part was dropped.
Related errors
- config path cannot be empty
- context_window must be greater than 0
- custom provider '{provider_id}' must set [providers.{provide
- unknown field '{field_key}' for built-in provider '{provider
- unknown field '{field_key}' for custom provider '{provider_i
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/1c0f34eca7df40a8.
Report an issue: GitHub.