Kuberwastaken/claurst · error · anyhow::Error
--dangerously-skip-permissions cannot be used with…
Error message
--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons
What it means
claurst deliberately refuses to start in permission-bypass mode (`--dangerously-skip-permissions`, which sets PermissionMode::BypassPermissions and lets the agent run arbitrary commands without approval) when the process is running as root or sudo on Unix. This mirrors the TypeScript implementation's guard: running an unrestricted agent with superuser privileges is considered too dangerous.
Solutions
- Run claurst as a non-root user (recommended): create/use a normal user account and rerun without sudo
- In Docker, add a `USER <nonroot>` directive or run with `docker run --user 1000:1000`
- If elevated filesystem access was the reason for sudo, grant the needed directories to the normal user instead of running the agent as root
- If you truly need bypass mode in a root container, re-exec as a non-root user inside the container (e.g. `su developer -c 'claurst --dangerously-skip-permissions ...'`); the guard itself is intentional and should not be bypassed as root
Example fix
// before: running bypass mode as root in a container docker run -it image claurst --dangerously-skip-permissions "fix tests" // -> bail: cannot be used with root/sudo privileges // after: run as a non-root user docker run -it --user 1000:1000 image claurst --dangerously-skip-permissions "fix tests"
Defensive patterns
Strategy: validation
Validate before calling
# Detect root before invoking bypass mode if [ "$(id -u)" -eq 0 ]; then echo "refusing: --dangerously-skip-permissions as root"; exit 1; fi exec claurst --dangerously-skip-permissions "$@"
Try / catch
# Wrap invocations so root is caught early with a clear message if ! out=$(claurst --dangerously-skip-permissions --print "task" 2>&1); then case "$out" in *root/sudo*) echo "Run as a non-root user.";; esac fi
Prevention
- Run containers as a non-root USER; pass --user to docker run
- Avoid sudo for developer CLIs; fix directory ownership instead
- In CI, check id -u before enabling bypass flags
- Treat the guard as intentional — do not work around it as root
When it happens
Trigger: Launching `claurst --dangerously-skip-permissions` while the effective UID is 0 (running as root, via `sudo claurst ...`, or inside a container/CI job that defaults to root), on a Unix platform (the check is `#[cfg(unix)]`).
Common situations: Docker containers that run as root by default; CI pipelines executing as root; developers habitually using sudo for the CLI; WSL or VM shells logged in as root.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Missing code or state in OAuth callback
- OAuth state mismatch — possible CSRF attack
- OAuth callback path mismatch: expected
- OAuth state mismatch — possible CSRF attack
- Failed to bind port
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/a3114b8ff6f77aaf.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/cli/src/main.rs:545
// --bare implies --no-claude-md: opening an untrusted repo in bare mode
// must not load or inject AGENTS.md memory files.
config.disable_claude_mds = cli.no_claude_md || cli.bare;
if cli.bare {
// Bare mode runs no event hooks. Drop any hooks resolved from
// settings so no `run_hooks` call site has anything to execute.
config.hooks.clear();
}
if let Some(sp) = cli.system_prompt.clone() {
config.custom_system_prompt = Some(sp);
}
if let Some(asp) = cli.append_system_prompt.clone() {
config.append_system_prompt = Some(asp);
}
if cli.dangerously_skip_permissions {
// Mirror TS setup.ts: block bypass mode when running as root/sudo.
#[cfg(unix)]
if nix::unistd::Uid::effective().is_root() {
anyhow::bail!(
"--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons"
);
}
config.permission_mode = PermissionMode::BypassPermissions;
} else {
config.permission_mode = cli.permission_mode.into();
}
config.additional_dirs = cli.add_dir.clone();
if cli.no_auto_compact {
config.auto_compact = false;
}
if cli.auto_commits {
config.auto_commits = Some(true);
}
config.project_dir = Some(cwd.clone());
if let Some(p) = &cli.provider {
config.provider = Some(p.clone());
}View on GitHub (pinned to b0637c97ec)