warpdotdev/warp · error · anyhow::Error
Refusing to expire API key without confirmation in non-inter
Error message
Refusing to expire API key without confirmation in non-interactive mode (use --force to bypass)
What it means
Safety guard on the destructive `api-key expire` command. Without `--force` the command requires an interactive `Confirm` prompt; when stdin is not a TTY (script, pipe, CI) the prompt cannot be shown, so the command refuses to run rather than silently expiring a key.
Source
Thrown at app/src/ai/agent_sdk/api_key.rs:170
}
};
let key = match resolve_api_key_identifier(&keys, &key_identifier) {
Ok(Some(key)) => key,
Ok(None) => {
ctx.terminate_app(TerminationMode::ForceTerminate, None);
return;
}
Err(err) => {
super::report_fatal_error(err, ctx);
return;
}
};
if !force {
if !io::stdin().is_terminal() {
super::report_fatal_error(
anyhow!(
"Refusing to expire API key without confirmation in non-interactive mode (use --force to bypass)"
),
ctx,
);
return;
}
let prompt = format!("Expire API key '{key}'?");
let should_expire = match Confirm::new(&prompt)
.with_default(false)
.with_help_message("This action takes effect immediately")
.prompt()
{
Ok(should_expire) => should_expire,
Err(InquireError::OperationCanceled | InquireError::OperationInterrupted) => {
ctx.terminate_app(TerminationMode::ForceTerminate, None);
return;
}View on GitHub (pinned to e72fd7aacb)
Solutions
- Add `--force` to the command for non-interactive contexts
- Run inside a real TTY (`ssh -t`, `docker run -it`, `script -e ...`) when you want the confirmation prompt
- For rotation automation, list keys first (`warp api-key list`) to dry-run, then expire with --force
Example fix
# before (in CI, no TTY) warp api-key expire ci-key # after warp api-key expire ci-key --force
Defensive patterns
Strategy: validation
Validate before calling
use std::io::IsTerminal;
fn expire_invocation_ok(force: bool) -> Result<(), String> {
if force || std::io::stdin().is_terminal() {
Ok(())
} else {
Err("stdin is not a TTY: pass --force or run interactively".into())
}
} Prevention
- Always pass --force in scripts and CI
- Use ssh -t / docker -it when the confirmation prompt is wanted
- List keys before expiring to make --force targets explicit
When it happens
Trigger: Running `warp api-key expire <key>` without `--force` in an environment where `io::stdin().is_terminal()` is false: CI jobs, cron, non-tty docker exec, piped stdin, some task runners.
Common situations: Automating key rotation in CI; running the CLI over ssh without -t; piping commands together; cleanup scripts inside containers.
Related errors
- Multiple API keys match '{key_identifier}'; specify the key
- Refusing to delete runner '{uid}' without confirmation in no
- API key '{key_identifier}' not found
- expiration duration is too large
- expiration behavior is required
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/dc54789c166a5982.
Report an issue: GitHub.