Hmbown/CodeWhale · error

import refused: non-interactive use requires explicit --yes…

Error message

import refused: non-interactive use requires explicit --yes after reviewing the plan

What it means

require_import_consent enforces an explicit consent gate before applying a bundle. If --yes was not passed and stdin is not a TTY (non-interactive run), no interactive confirmation prompt can be shown, so the import is refused instead of mutating configuration without review.

Solutions

  1. Run the import once with the dry-run/plan output to review what will be added/changed.
  2. Re-run with `--yes` to confirm non-interactive application.
  3. If the run should be interactive, ensure a real TTY is attached (no stdin redirect/piping).

Example fix

// before (CI)
codewhale config import bundle.toml
// after
codewhale config import bundle.toml --yes
Defensive patterns

Strategy: validation

Validate before calling

if !std::io::stdin().is_terminal() && !args_yes { eprintln!("non-interactive: pass --yes after reviewing the plan"); std::process::exit(2); }

Try / catch

match run_import(&args, &store) {
    Err(e) if e.to_string().contains("requires explicit --yes") => {
        eprintln!("review the plan, then re-run with --yes");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running `config import` (apply_bundle path) from CI, a script, or any piped/non-TTY stdin without the --yes flag.

Common situations: Automation pipelines importing bundles headlessly; Docker/CI steps where stdin is not a terminal; forgetting --yes after previously running interactively.

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


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

Appendix: source

Thrown at crates/cli/src/config_bundles.rs:1428

    let (_file, path) = backup
        .keep()
        .map_err(|error| error.error)
        .context("persisting bundle backup")?;
    Ok(path)
}

// ---------------------------------------------------------------------------
// Consent
// ---------------------------------------------------------------------------

/// Require explicit consent before mutating: interactive sessions get a
/// prompt; headless runs require `--yes`.
pub fn require_import_consent(yes: bool, plan: &ImportPlan) -> Result<()> {
    if yes {
        return Ok(());
    }
    if !std::io::stdin().is_terminal() {
        bail!(
            "import refused: non-interactive use requires explicit --yes after reviewing the plan"
        );
    }
    print!(
        "Apply this bundle ({} added, {} changed)? Type 'yes': ",
        plan.added.len(),
        plan.changed.len()
    );
    use std::io::Write;
    std::io::stdout().flush()?;
    let mut answer = String::new();
    std::io::stdin()
        .read_line(&mut answer)
        .context("reading import consent")?;
    if answer.trim() != "yes" {
        bail!("import cancelled; no configuration was changed");
    }
    Ok(())

View on GitHub (pinned to 73e0f67d83)