Skip to content

min init destroys an existing minimal.toml with no backup; --no-input is never read and confirm() treats EOF as yes #1032

Description

@norrietaylor

Fixed with: #1053

Surface: min init · Severity: High · Class: data loss
Source: lib.rs:2514-2538 (run_init_flow), lib.rs:879 (confirm)

Re-running min init in a project that already has a minimal.toml silently replaces it.
No warning, no backup, no diff. The banner says “Will create” when the file already exists;
the result says “Created” when it replaced.

Reproduce

min -C proj init -y                 # packages = ["base","vim"]
min -C proj add --session ripgrep   # packages = ["base","vim","ripgrep"]
min -C proj init -y                 # "Created /.../minimal.toml"
grep packages proj/minimal.toml     # packages = ["base","vim"]   <- edits gone

--no-input does not stop it

Documented behaviour of --no-input: “Skip interactive prompts that need a terminal… When a
choice is ambiguous, the command errors with a list of candidates instead of opening a
picker.”
Observed:

min --no-input -C proj init
  Will create /.../minimal.toml:
  Continue? [Y/n] Created /.../minimal.toml
  exit 0    # wrote anyway

Plain min init with a non-TTY stdin behaves the same.

Cause

--no-input is not merely weakened on this path — it is never read. Neither cmd_init nor
run_init_flow looks at global.no_input at all. The auto-accept comes from confirm()
(lib.rs:879), which reads stdin and returns the default — true — on the empty string
EOF hands it.

Re-run on main: packages = ["base","vim","ripgrep"] -> ["base","vim"], exit 0, no backup
written.

Fix

Refuse when the file exists unless --force; make --no-input/non-TTY a hard error on the
overwrite path rather than an implicit yes.

Shared failure mode

One of four high-severity findings with the same shape: a command performs a consequential action while its stated safeguard does not fire, or reports success for a condition it never checked. The others are min init overwriting an existing config, bare min creating a session under --no-input before failing, and min completions install reporting success for shells that will never load the file.

The reference implementation already ships in this binary: min session destroy --all refuses non-interactively and names the flag that would proceed (error: refusing to destroy all sessions without confirmation; pass --force, exit 1). That message is the convention the other three should copy.


QA sweep of the published min help tree against a live local-minvmd daemon (min 0.5.0-rc3.dev.31.gc1375225, HEAD c137522); every finding re-executed against main at df22d71 and read back to source. Ledger finding F2 (confirmed on main).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions