zeroclaw-labs/zeroclaw · error · anyhow::Error
cannot resolve SOP path '{}'
Error message
cannot resolve SOP path '{}' What it means
resolve_existing_ancestor walks the path upward via file_name()/parent(); when a path has no file_name (empty path '' or filesystem root '/') or no parent, the (Some(name), Some(parent)) match arm fails and the walk cannot continue. This error means the path being resolved is degenerate - there is no component left to resolve. It surfaces through ensure_within_root during apply_proposal path checks.
Source
Thrown at crates/zeroclaw-runtime/src/sop/procedural_memory.rs:436
.with_context(|| format!("canonicalize '{}'", current.display()))?;
for name in remainder.iter().rev() {
resolved.push(name);
}
return Ok(resolved);
}
match (current.file_name(), current.parent()) {
(Some(name), Some(parent)) => {
let component = Path::new(name);
if component
.components()
.any(|c| !matches!(c, Component::Normal(_)))
{
bail!("unsafe SOP path component '{}'", name.to_string_lossy());
}
remainder.push(name);
current = parent;
}
_ => bail!("cannot resolve SOP path '{}'", path.display()),
}
}
}
fn ensure_relative_component(component: &str) -> Result<()> {
let path = Path::new(component);
if path
.components()
.any(|c| !matches!(c, Component::Normal(_)))
{
bail!("unsafe SOP path component");
}
Ok(())
}
fn hash_sop_dir(dir: &Path) -> Result<String> {
let mut hasher = Sha256::new();
for name in ["SOP.toml", "SOP.md"] {View on GitHub (pinned to 88bb9c8533)
Solutions
- Set sops_dir to a concrete subdirectory (never '' or '/'), e.g. '/var/lib/zeroclaw/sops'
- Verify install_root is a real directory path, not the filesystem root
- Guard callers: reject empty or '/' install roots before invoking apply_proposal
Example fix
# before (config) sops_dir = "/" # after sops_dir = "sops" # resolved under install_root, non-root
Defensive patterns
Strategy: validation
Validate before calling
fn resolvable_path(p: &Path) -> bool {
!p.as_os_str().is_empty() && p.file_name().is_some() && p.parent().is_some()
} Try / catch
Err(e) if e.to_string().contains("cannot resolve SOP path") => {
// log the offending path from the message; fix the config entry that produced it
} Prevention
- Forbid empty or '/' sops_dir/install_root values in config validation
- Default sops_dir to a named subdirectory (e.g. 'sops') when unset
- Fail config load early on degenerate paths instead of failing at apply time
When it happens
Trigger: apply_proposal path containment checks receiving an empty path or '/' as sops_root or target - e.g. sops_dir misconfigured to '/' or '', making resolve_sops_dir produce a root-level path with no name/parent components.
Common situations: An empty or root sops_dir setting in config, an install_root of '/' in containerized deployments, or string manipulation upstream producing an empty path string.
Related errors
- capability '{}' requires authored `with` configuration to be
- SOP name does not contain a safe path component
- unsafe SOP path component '{}'
- matrix: `homeserver` is required
- Cannot persist empty Telegram identity
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/7556841b7faaedcd.
Report an issue: GitHub.