{"record":{"id":"31b21b50f7c343c5","repo":"xai-org/grok-build","slug":"doctor-fixes-require-interactive-input-and-output","errorCode":null,"errorMessage":"Doctor fixes require interactive input and output.","messagePattern":"Doctor fixes require interactive input and output\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/doctor_cmd/mod.rs","lineNumber":53,"sourceCode":"    pub yes: bool,\n}\n\npub fn run(args: DoctorArgs) -> Result<()> {\n    match args.command {\n        None => run_report(args.json, &mut std::io::stdout().lock()),\n        Some(DoctorCommand::Fix(fix)) => run_fix(\n            fix,\n            std::io::stdin().is_terminal(),\n            &mut std::io::stdin().lock(),\n            &mut std::io::stdout().lock(),\n        ),\n    }\n}\n\npub fn run_with_writer(args: DoctorArgs, writer: &mut impl Write) -> Result<()> {\n    match args.command {\n        None => run_report(args.json, writer),\n        Some(_) => anyhow::bail!(\"Doctor fixes require interactive input and output.\"),\n    }\n}\n\nfn run_report(json_output: bool, writer: &mut impl Write) -> Result<()> {\n    let report = collect_report();\n    write_report(&report, json_output, writer)\n}\n\npub fn collect_report() -> DiagnosticReport {\n    let terminal = crate::terminal::standalone_terminal_context();\n    let report = collect_report_with(crate::diagnostics::probes::collect_standalone(&terminal));\n    configured_report_for_terminal(report, &terminal)\n}\n\nfn configured_report_for_terminal(\n    report: DiagnosticReport,\n    terminal: &crate::terminal::TerminalContext,\n) -> DiagnosticReport {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/doctor_cmd/mod.rs#L35-L71","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the doctor fix subcommand directly in an interactive terminal instead of via `run_with_writer`.","If a report is enough, call doctor without a subcommand so `run_report` executes.","Use the interactive entry point (TTY) for fixes, or pass the appropriate non-interactive flag at the CLI level.","Apply the underlying fix manually based on the doctor report output."],"exampleFix":"// before (piped, writer entry)\necho 'doctor fix-config' | grok\n// after\ngrok doctor fix-config   # in an interactive terminal","handlingStrategy":"validation","validationCode":"if doctor_args.command.is_some() && !std::io::stdin().is_terminal() {\n    eprintln!(\"Doctor fixes need an interactive terminal; run without piping.\");\n    std::process::exit(1);\n}","typeGuard":null,"tryCatchPattern":"match doctor_cmd::run_with_writer(args, &mut w) {\n    Err(e) if e.to_string().contains(\"require interactive input\") => {\n        eprintln!(\"Run the fix subcommand directly in a TTY, or use the report-only mode.\");\n    }\n    other => other?,\n}","preventionTips":["Only run doctor fix subcommands in an interactive terminal","In CI/scripts, use the report-only mode and apply fixes manually or in a TTY step","Don't call run_with_writer with a Some(command); it is report-only by design"],"tags":["doctor","interactive-tty","cli"],"backgroundTag":"interactive-terminal-required","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}