Hmbown/CodeWhale · error

{message}

Error message

{message}

What it means

This refusal is raised before spawning any process when the tool detects that the command would inherit the agent's own interactive terminal and take over its foreground TTY. On Unix, foreground process-group ownership cannot be transferred safely from the running TUI (cooked-mode Ctrl+C would terminate both parent and child), so the tool fails closed rather than spawning. The concrete message is produced by `inherited_interactive_terminal_refusal()` and explains the supported alternatives.

Solutions

  1. Run the command with `background: true, tty: true`, then continue it with `action: "interact"` and the returned `task_id`
  2. Use `terminal/run` and `terminal/send` for a persistent interactive PTY lane
  3. Launch the command in a new terminal window instead of the agent's terminal
  4. For non-interactive work, omit `interactive: true` entirely

Example fix

// before
{ "command": "htop", "interactive": true }
// after
{ "command": "htop", "tty": true, "background": true }
Defensive patterns

Strategy: validation

Validate before calling

// Unix: interactive inheritance is never allowed, check the flag first
if request.interactive {
    // route through background tty or terminal/run instead
}

Prevention

When it happens

Trigger: Calling the shell tool with `interactive: true` on Unix, so the child would inherit the operator's live terminal; the guard `inherited_interactive_terminal_refusal()` returns Some(message) for all Unix targets (with a variant text on ohos) and None only on non-Unix platforms.

Common situations: Agents attempt to run interactive/foreground terminal programs (vim, top, ssh with prompts) attached to the live terminal; porting or testing on Linux/macOS where interactive inheritance is never allowed; behavior differs across platforms since non-Unix builds skip this check.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/079707ca3ca10ac3. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tools/shell.rs:2233

    pub fn execute_interactive_with_policy_env(
        &mut self,
        command: &str,
        working_dir: Option<&str>,
        timeout_ms: u64,
        policy_override: Option<ExecutionSandboxPolicy>,
        extra_env: HashMap<String, String>,
    ) -> Result<ShellResult> {
        crate::shell_dispatcher::ShellDispatcher::log_exec(command);

        // A new Unix process group that inherits the terminal is not its
        // foreground owner. Letting it read stdin triggers SIGTTIN; sharing
        // Codewhale's group instead would make cooked-mode Ctrl+C terminate
        // both parent and child. Until this path owns a complete POSIX job-
        // control lease, fail closed before spawning. Persistent PTY tools
        // already provide a safe interactive lane without taking over the
        // operator's live terminal.
        if let Some(message) = inherited_interactive_terminal_refusal() {
            return Err(anyhow!(message));
        }

        let work_dir = working_dir.map_or_else(|| self.default_workspace.clone(), PathBuf::from);
        validate_shell_working_dir(&work_dir, working_dir.is_none())?;

        let timeout_ms = timeout_ms.clamp(1000, 600_000);
        let policy = policy_override.unwrap_or_else(|| self.sandbox_policy.clone());

        let spec = CommandSpec::shell(command, work_dir.clone(), Duration::from_millis(timeout_ms))
            .with_policy(policy)
            .with_env(extra_env);
        let exec_env = self.sandbox_manager.prepare(&spec);

        Self::execute_interactive_sandboxed(command, &work_dir, timeout_ms, &exec_env)
    }

    /// Execute command synchronously with timeout (sandboxed).
    fn execute_sync_sandboxed(

View on GitHub (pinned to 73e0f67d83)