xai-org/grok-build · error

hook write-deny ensure failed: {e}

Error message

hook write-deny ensure failed: {e}

What it means

Raised in `SandboxManager::apply` when `ensure_grok_hook_slots` fails to set up the write-deny hook files under the Grok home directory for profiles that require hook-based write denial. The hook layer is what enforces write denies outside the raw sandbox namespace, so failing to ensure those slots means the sandbox cannot be safely activated and apply aborts.

Source

Thrown at crates/codegen/xai-grok-sandbox/src/lib.rs:197

        let net_restricted = profile.restricts_network();
        Self {
            profile,
            logger: SandboxLogger::new(),
            net_restricted,
            applied: false,
        }
    }
    /// Apply the sandbox to the current process. **Irreversible.**
    /// Degrades gracefully if the platform doesn't support it.
    #[cfg(all(feature = "enforce", unix))]
    pub fn apply(&mut self, workspace: &Path) -> anyhow::Result<()> {
        if self.profile == ProfileName::Off {
            tracing::info!("Sandbox disabled (profile: off)");
            return Ok(());
        }
        if requires_hook_write_deny(&self.profile, workspace) {
            xai_grok_config::ensure_grok_hook_slots(paths::grok_home().as_path())
                .map_err(|e| anyhow::anyhow!("hook write-deny ensure failed: {e}"))?;
        }
        hook_write_deny::maybe_install_namespace_lockdown_inside_bwrap(&self.profile, workspace)
            .map_err(|e| anyhow::anyhow!("{e}"))?;
        let config = profiles::load_sandbox_config(workspace);
        let mut resolved = self.profile.resolve_profile(workspace, &config)?;
        self.net_restricted = resolved.restrict_network;
        let support = Sandbox::support_info();
        if !support.is_supported {
            tracing::warn!(
                details = %support.details,
                "Sandbox not supported on this platform, continuing without sandbox"
            );
            self.logger.log(SandboxEvent::apply_failed(
                &self.profile.to_string(),
                workspace,
                &support.details,
            ));
            return Ok(());

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Check the inner `{e}` to see whether it is a filesystem permission or a hook-content validation error.
  2. Ensure ~/.grok (paths::grok_home()) exists and is writable by the current user: `mkdir -p ~/.grok && chown -R $USER ~/.grok`.
  3. Remove or fix stale/invalid hook files under the grok home so ensure can rewrite them.
  4. Re-run the apply command; if running under a container, mount the grok home as writable.

Example fix

# before (fails)
sudo grok-worktree ...   # creates ~/.grok hook files owned by root
# after
sudo chown -R $USER ~/.grok
grok-worktree ...        # apply can now ensure hook slots
Defensive patterns

Strategy: try-catch

Validate before calling

fn grok_home_writable() -> Result<(), String> {
    let home = xai_grok_sandbox::paths::grok_home();
    if !home.exists() {
        std::fs::create_dir_all(&home).map_err(|e| e.to_string())?;
    }
    let probe = home.join(".write-test");
    std::fs::write(&probe, b"ok").map_err(|e| e.to_string())?;
    std::fs::remove_file(&probe).map_err(|e| e.to_string())
}
// call before manager.apply(...)

Try / catch

if let Err(e) = manager.apply(workspace) {
    let msg = e.to_string();
    if msg.contains("hook write-deny ensure failed") {
        eprintln!("Hook setup failed under {}: fix permissions or stale hook files\n{e:#}",
                  grok_home().display());
    } else {
        eprintln!("sandbox apply failed: {e:#}");
    }
    std::process::exit(1);
}

Prevention

When it happens

Trigger: The profile (per `requires_hook_write_deny`) needs hook write-deny but creating/validating the hook slot files under paths::grok_home() fails — e.g. directory not writable, disk full, an existing hook file with invalid content, or a config-library alias validation error.

Common situations: ~/.grok owned by root or another user after a sudo run; read-only home or restricted container; stale/corrupt hook JSON left by an older version; XDG config pointing grok home somewhere unwritable.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/b440b96a39195395. Report an issue: GitHub.