warpdotdev/warp · error · anyhow::Error

Refusing to delete runner '{uid}' without confirmation in no

Error message

Refusing to delete runner '{uid}' without confirmation in non-interactive mode (use --force to bypass)

What it means

A deliberate safety guard in runner deletion: without a TTY there is no way to show the confirm prompt, and silently skipping the delete would mislead scripts into thinking it happened. Non-interactive runs without --force therefore fail loudly with a non-zero exit so callers notice.

Source

Thrown at app/src/ai/agent_sdk/runner.rs:213

            },
            |_, result: Result<()>, ctx| finish_command(result, ctx),
        );
    }
}

impl warpui::Entity for RunnerCommandRunner {
    type Event = ();
}
impl SingletonEntity for RunnerCommandRunner {}

/// Prompt the user to confirm deletion of a runner.
///
/// Returns `Ok(true)`/`Ok(false)` for an interactive confirm/decline. In
/// non-interactive mode (no TTY) without `--force`, returns `Err` so the caller
/// fails loudly (non-zero exit) instead of silently skipping the delete.
fn confirm_delete(uid: &str, is_terminal: bool) -> Result<bool> {
    if !is_terminal {
        return Err(anyhow!(
            "Refusing to delete runner '{uid}' without confirmation in non-interactive mode (use --force to bypass)"
        ));
    }

    Ok(inquire::Confirm::new(&format!("Delete runner '{uid}'?"))
        .with_default(false)
        .prompt()
        .unwrap_or_default())
}

/// Resolve a runner by UID or (unambiguous) name from a fetched list.
fn resolve_runner<'a>(
    runners: &'a [Runner],
    id: Option<&str>,
    name: Option<&str>,
) -> Result<&'a Runner> {
    if let Some(id) = id {
        return runners

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Add --force to the delete command in scripts and CI
  2. Run the command in an interactive terminal to get the y/N prompt
  3. In wrappers, detect non-TTY and require explicit operator confirmation before delegating

Example fix

# before
warp runner delete rnr_123   # inside CI: refuses, non-zero exit

# after
warp runner delete rnr_123 --force
Defensive patterns

Strategy: validation

Validate before calling

# Decide interactiveness up front and pass explicit intent
if [ -t 0 ]; then
  warp runner delete "$uid"
else
  warp runner delete "$uid" --force
fi

Try / catch

out=$(warp runner delete "$uid" 2>&1) || { case "$out" in *'without confirmation in non-interactive mode'*) echo 're-run with --force in scripts' >&2; exit 1;; *) echo "$out" >&2; exit 1;; esac; }

Prevention

When it happens

Trigger: `warp runner delete <uid>` executed where stdin/stdout is not a terminal (CI job, cron, piped script) and --force was not passed, so confirm_delete gets is_terminal=false.

Common situations: CI cleanup jobs; scripts developed interactively (where the prompt worked) later run headless; output piped through another command, making is_terminal false.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/6314d552dab2caed. Report an issue: GitHub.