Hmbown/CodeWhale · error
config path cannot contain '..' components
Error message
config path cannot contain '..' components
What it means
normalize_config_file_path rejects config paths containing '..' components before they are resolved. This prevents path traversal out of the intended config directory and avoids ambiguous resolution. It is a deliberate security/validation guard, not a bug.
Solutions
- Use an absolute path with no '..' components
- Use a relative path that starts from the intended directory without '..' (e.g. "codewhale/config.toml")
- Resolve the '..' yourself (e.g. via std::fs::canonicalize) before passing the path
Example fix
// before
load_config(PathBuf::from("../codewhale/config.toml"))
// after
let path = std::fs::canonicalize("../codewhale/config.toml")?;
load_config(path) Defensive patterns
Strategy: validation
Validate before calling
fn no_parent_components(p: &std::path::Path) -> bool {
use std::path::Component;
!p.components().any(|c| matches!(c, Component::ParentDir))
} Type guard
fn safe_config_path(p: &str) -> Option<std::path::PathBuf> {
use std::path::Component;
let path = std::path::PathBuf::from(p);
(!path.components().any(|c| matches!(c, Component::ParentDir))).then_some(path)
} Try / catch
match normalize_config_file_path(path) {
Ok(p) => p,
Err(e) if e.to_string().contains("'..' components") => {
eprintln!("rewrite the path without '..'; got: {}", path.display());
std::process::exit(2);
}
Err(e) => return Err(e),
} Prevention
- Always express config paths absolutely
- Canonicalize user-supplied paths before passing them in
- Ban '..' in path-templating scripts
When it happens
Trigger: Passing a config path such as "/etc/../../home/user/config.toml", "../config.toml", or "a/../config.toml" to the config loader.
Common situations: Users expressing 'the config one level up' with relative paths, scripts templating paths with ../ segments, or symlink-following setups where users expect .. to be normalized silently.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Codewhale credentials directory must be lexically normalized
- config path cannot be empty
- config path must include a file name
- Fleet artifact path must stay within the workspace
- managed directory path cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/0a7a1137bc1fa432.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/lib.rs:6763
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
.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")?;View on GitHub (pinned to 73e0f67d83)