jdx/mise · error
mise prune requires confirmation but there was nobody to…
Error message
mise prune requires confirmation but there was nobody to ask; pass --yes to prune non-interactively
What it means
`mise prune` asks for confirmation before removing tool versions. When the command runs non-interactively (no TTY/stdin to prompt), confirmation is Unavailable; unless --yes (UnavailableConfirmation other than Decline) was passed, mise aborts rather than deleting tools without consent.
Solutions
- Pass --yes: `mise prune --yes` to confirm removals non-interactively
- Restrict scope so no confirmation is needed, e.g. `mise prune <tool>@<version>` where policy allows
- Run prune interactively in a TTY session instead
Example fix
// before (CI) run: mise prune // after run: mise prune --yes
Defensive patterns
Strategy: validation
Validate before calling
if [ ! -t 0 ]; then PRUNE_FLAGS="--yes"; fi; mise prune $PRUNE_FLAGS
Prevention
- Always pass --yes in CI/scripts for destructive mise commands
- Guard interactive commands with a TTY check
- Scope prune narrowly so unattended runs are predictable
When it happens
Trigger: Running `mise prune` in CI, scripts, or piped contexts where ui::confirm cannot read an answer, without passing --yes.
Common situations: CI pipeline cleanup steps; cron jobs; shell scripts piping prune output; Dockerfile RUN steps without -it.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- sudo requires a password but no TTY is available. Run…
- adoption requires confirmation; review the directory and…
- app target is outside an allowed Applications directory
- artifact target has changed
- artifact target is now claimed by another cask
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5b397b322e941489.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/prune.rs:238
return Ok(());
}
// Ask about everything first, then remove. A prompt in the middle of a
// live region has to pause it, and the answers are the same either way.
let mut confirmed = Vec::with_capacity(to_delete.len());
for (p, tv) in to_delete {
if let Some(needed) = explain {
explain_removal(&tv, needed);
}
if Settings::get().yes {
confirmed.push((p, tv));
continue;
}
match prompt::confirm_with_all(format!("remove {} ?", tv))? {
Confirmation::Yes => confirmed.push((p, tv)),
Confirmation::No | Confirmation::Unanswered => {}
Confirmation::Unavailable if unavailable == UnavailableConfirmation::Decline => {}
Confirmation::Unavailable => eyre::bail!(
"mise prune requires confirmation but there was nobody to ask; pass --yes to prune non-interactively"
),
}
}
let mut progress = removal_progress(
&mpr,
confirmed
.iter()
.map(|(_, tv)| (removal_key(tv), tv.style())),
);
for (p, tv) in confirmed {
let tool = progress
.as_ref()
.and_then(|progress| progress.start_tool(&removal_key(&tv)));
let pr = match &tool {
Some(tool) => tool.reporter(),
None => mpr.add(&tv.style()),View on GitHub (pinned to 533346cc37)