xai-org/grok-build · error

Doctor fixes require interactive input and output.

Error message

Doctor fixes require interactive input and output.

What it means

`doctor_cmd::run_with_writer` only supports the report path when driven with an injected writer. Any explicit doctor subcommand (a fix) is rejected because fixes need a real interactive terminal for confirmation prompts and terminal output, which the writer-based (non-TTY) entry point cannot provide.

Source

Thrown at crates/codegen/xai-grok-pager/src/doctor_cmd/mod.rs:53

    pub yes: bool,
}

pub fn run(args: DoctorArgs) -> Result<()> {
    match args.command {
        None => run_report(args.json, &mut std::io::stdout().lock()),
        Some(DoctorCommand::Fix(fix)) => run_fix(
            fix,
            std::io::stdin().is_terminal(),
            &mut std::io::stdin().lock(),
            &mut std::io::stdout().lock(),
        ),
    }
}

pub fn run_with_writer(args: DoctorArgs, writer: &mut impl Write) -> Result<()> {
    match args.command {
        None => run_report(args.json, writer),
        Some(_) => anyhow::bail!("Doctor fixes require interactive input and output."),
    }
}

fn run_report(json_output: bool, writer: &mut impl Write) -> Result<()> {
    let report = collect_report();
    write_report(&report, json_output, writer)
}

pub fn collect_report() -> DiagnosticReport {
    let terminal = crate::terminal::standalone_terminal_context();
    let report = collect_report_with(crate::diagnostics::probes::collect_standalone(&terminal));
    configured_report_for_terminal(report, &terminal)
}

fn configured_report_for_terminal(
    report: DiagnosticReport,
    terminal: &crate::terminal::TerminalContext,
) -> DiagnosticReport {

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Run the doctor fix subcommand directly in an interactive terminal instead of via `run_with_writer`.
  2. If a report is enough, call doctor without a subcommand so `run_report` executes.
  3. Use the interactive entry point (TTY) for fixes, or pass the appropriate non-interactive flag at the CLI level.
  4. Apply the underlying fix manually based on the doctor report output.

Example fix

// before (piped, writer entry)
echo 'doctor fix-config' | grok
// after
grok doctor fix-config   # in an interactive terminal
Defensive patterns

Strategy: validation

Validate before calling

if doctor_args.command.is_some() && !std::io::stdin().is_terminal() {
    eprintln!("Doctor fixes need an interactive terminal; run without piping.");
    std::process::exit(1);
}

Try / catch

match doctor_cmd::run_with_writer(args, &mut w) {
    Err(e) if e.to_string().contains("require interactive input") => {
        eprintln!("Run the fix subcommand directly in a TTY, or use the report-only mode.");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `run_with_writer(args, writer)` (the public programmatic entry) with `args.command == Some(_)` — i.e. any `doctor <fix-subcommand>` invoked through the writer API or in a non-interactive pipeline.

Common situations: Scripting doctor fixes in CI with piped stdout; invoking the doctor fix API from tests or another crate via the writer entry point; wrapping the CLI in a tool that captures output.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/31b21b50f7c343c5. Report an issue: GitHub.