Hmbown/CodeWhale · error

reviewed plugin stdio cwd escaped its staged root

Error message

reviewed plugin stdio cwd escaped its staged root

What it means

For stdio MCP servers contributed by a reviewed plugin, any configured working directory must live inside the plugin's staged root; the launch is refused when the cwd does not start with the staged-root prefix. This keeps plugin-launched processes from executing with a working directory outside the reviewed sandbox.

Source

Thrown at crates/tui/src/mcp.rs:701

            if path.is_absolute() && path.starts_with(staged_root) && path.is_file() {
                launch.args[index] = launch.bind_file(staged_root, path, &validated.file_hashes)?;
            }
        }
        #[cfg(target_os = "macos")]
        if is_node_command(command) {
            let entry_index = args.iter().position(|argument| {
                let path = Path::new(argument);
                path.is_absolute()
                    && path.starts_with(staged_root)
                    && path.extension().is_some_and(|extension| extension == "mjs")
            });
            if let Some(entry_index) = entry_index {
                launch.args = node_esm_descriptor_args(&launch.args, entry_index);
            }
        }
        if let Some(cwd) = cwd {
            if !cwd.starts_with(staged_root) {
                anyhow::bail!("reviewed plugin stdio cwd escaped its staged root");
            }
            launch.bind_cwd(cwd)?;
        }
        // A final authority pass detects any non-executed companion/config
        // drift while handles were opened. Execution itself uses the handles.
        self.validate_before_stdio_spawn(server_name)?;
        Ok(launch)
    }

    fn required_capability(&self) -> crate::plugins::activation::PluginActivationCapability {
        if self.approved_remote_endpoint.is_some() {
            crate::plugins::activation::PluginActivationCapability::McpRemote
        } else {
            crate::plugins::activation::PluginActivationCapability::McpStdio
        }
    }

    fn validate_before_use(&self, server_name: &str, operation: &str) -> Result<()> {

View on GitHub (pinned to 8880682c63)

Solutions

  1. Set the plugin server's cwd to a directory inside its stage root, or omit cwd entirely
  2. If the tool genuinely needs another working directory, run it as a user-configured MCP server instead of through the plugin
  3. Re-release the plugin with a compliant manifest and redo review/enable

Example fix

// before (plugin manifest): cwd outside the stage
{ "command": "node", "args": ["server.mjs"], "cwd": "/home/me/project" }
// after: omit cwd, or point it inside the staged root
{ "command": "node", "args": ["server.mjs"] }
Defensive patterns

Strategy: validation

Validate before calling

// Validate a configured cwd against the stage root before launch
fn cwd_within(stage_root: &std::path::Path, cwd: Option<&std::path::Path>) -> bool {
    cwd.map_or(true, |c| c.starts_with(stage_root))
}

Prevention

When it happens

Trigger: A plugin manifest or server config sets cwd to a project, home, or any directory outside the stage; a relative cwd that does not lexically start with the absolute staged-root prefix; symlinks making the configured path fall outside the prefix.

Common situations: Plugins written for older layouts that assumed arbitrary cwd, manifest templates reusing a user workspace path, tools that need repo-relative execution but were packaged as reviewed plugins.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/3241d0e5ed6b0e57. Report an issue: GitHub.