Hmbown/CodeWhale · error
persistent path allow rules must stay within the workspace
Error message
persistent path allow rules must stay within the workspace
What it means
Persistent path allow rules are normalized relative to the rule's workspace scope; if `normalize_workspace_relative_path` returns `None` (path escapes the workspace, e.g. via `..` or an absolute path) or an empty path, the rule is rejected so config can never contain an allow rule pointing outside the workspace.
Solutions
- Use a workspace-relative path that stays inside the workspace (e.g. `src/**` or `target/`)
- Strip leading absolute prefixes and re-express the path relative to the workspace directory
- Remove the `path` field and constrain the rule by exact `command` instead
Example fix
// before
PermissionRule { path: Some("/home/user/project/target".into()), .. }
// after
PermissionRule { path: Some("target".into()), .. } Defensive patterns
Strategy: validation
Validate before calling
use codewhale_execpolicy::normalize_workspace_relative_path;
fn path_stays_in_workspace(path: &str, workspace: &Path) -> bool {
normalize_workspace_relative_path(path, workspace)
.map_or(false, |p| !p.is_empty())
} Try / catch
match config.append_persistent_allow_rules(&rules) {
Err(e) if e.to_string().contains("stay within the workspace") => {
// convert path to workspace-relative and retry
}
result => result?,
} Prevention
- Only offer workspace-relative paths in path-allow UIs
- Reject absolute paths and `..` segments at input time
- Run `normalize_workspace_relative_path` on user paths before building rules
When it happens
Trigger: Calling the persistent allow-rule API with `path: Some(..)` where the path is absolute, contains `..` escaping the workspace root, or normalizes to empty (e.g. pointing at the workspace root itself with empty result).
Common situations: Users pasting absolute paths like `/etc` or `C:\dir` into a path allow field; paths like `../shared` that resolve outside the project; an empty path string left in a rule.
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 cannot contain '..' components
- config path must include a file name
- managed directory path cannot be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/41b19d93a3fb9d70.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/lib.rs:5353
else {
bail!("persistent allow rules must be scoped to a workspace");
};
if rule.command.is_some() && !rule.command_exact {
bail!("persistent command allow rules must use exact matching");
}
if rule.command.is_none() && rule.path.is_none() {
bail!("persistent allow rules must match an exact command or path");
}
if let Some(command) = rule.command.as_deref()
&& command.trim().is_empty()
{
bail!("persistent command allow rules must not be empty");
}
if let Some(path) = rule.path.as_deref()
&& codewhale_execpolicy::normalize_workspace_relative_path(path, &workspace)
.is_none_or(|path| path.is_empty())
{
bail!("persistent path allow rules must stay within the workspace");
}
}
self.append_permission_rules(rules, PermissionAction::Allow)
}
fn append_permission_rules(
&mut self,
rules: &[ToolAskRule],
expected_action: PermissionAction,
) -> Result<usize> {
if rules.is_empty() {
return Ok(0);
}
if rules.iter().any(|rule| rule.action != expected_action) {
bail!(
"permission rule action does not match requested {:?} persistence",
expected_action
);View on GitHub (pinned to 73e0f67d83)