jdx/mise · error

piped stdin is available

Error message

piped stdin is available

What it means

A Rust panic when writing input to a spawned elevated helper: the child process was configured with piped stdin implicitly via Stdio::piped() (or default piping in this builder), and the code expects child.stdin to be Some when taking it. It fires only if the spawn configuration was changed so stdin is not piped (e.g. Stdio::inherit() or null), making the take() return None.

Solutions

  1. Ensure the Command is built with .stdin(Stdio::piped()) before spawn in run_with_input
  2. Check no platform-specific builder overrides stdin on this OS
  3. If input writing can fail, handle io::Error from write_all instead of relying on the expect
  4. Report a bug with OS and command if hit in an unmodified build

Example fix

// before
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
// after
.stdin(Stdio::piped())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
Defensive patterns

Strategy: validation

Validate before calling

if !cmd_builder_stdin_is_piped { return Err(anyhow!("helper stdin not piped")); }

Type guard

fn stdin_piped(child: &Child) -> Option<&mut ChildStdin> { /* use child.stdin.take() result */ None.or(child.stdin.as_mut()) }

Try / catch

match child.stdin.take() {
    Some(mut stdin) => stdin.write_all(input)?,
    None => bail!("internal error: helper stdin was not piped"),
}

Prevention

When it happens

Trigger: Running run_with_input (elevated bootstrap helper with input) after someone changed the Command's stdin configuration away from piped; on stock code it cannot fire.

Common situations: Development edits to the sudo/bootstrap Command builder; custom builds where stdin was switched to inherit and input is still written.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/244053dc46729411. Report an issue: GitHub.

Appendix: source

Thrown at src/system/sudo.rs:234

    let argv = argv(program, args);
    let manual_cmd = std::iter::once("sudo".to_string())
        .chain(std::iter::once(program.to_string()))
        .chain(args.iter().cloned())
        .collect::<Vec<_>>()
        .join(" ");
    ensure_elevation_available(&manual_cmd)?;
    let _progress_pause = pause_progress_for_child();
    info!("$ {}", argv.join(" "));
    let mut child = Command::new(&argv[0])
        .args(&argv[1..])
        .stdin(Stdio::piped())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn()?;
    child
        .stdin
        .take()
        .expect("piped stdin is available")
        .write_all(input)?;
    let status = child.wait()?;
    if !status.success() {
        bail!("elevated bootstrap helper failed with {status}");
    }
    Ok(())
}

/// Run one elevated helper with a private stdin payload and capture stdout.
/// Stderr remains attached to the terminal for sudo prompts and diagnostics.
pub(crate) fn run_with_input_output(
    program: &str,
    args: &[String],
    input: &[u8],
) -> Result<Vec<u8>> {
    let argv = argv(program, args);
    let manual_cmd = std::iter::once("sudo".to_string())
        .chain(std::iter::once(program.to_string()))

View on GitHub (pinned to 533346cc37)