PRQL/prql · error
internal error: command does not take input & output
Error message
internal error: command does not take input & output
What it means
`read_input` reads the query source from the command's IoArgs (input path or stdin). If the active subcommand has no `IoArgs` attached, `io_args()` returns None and this internal-error is raised. It marks a programming mistake in wiring the command enum, not bad user input.
Solutions
- Ensure the subcommand struct includes an `IoArgs` field and that `io_args()` maps the variant to it
- Route commands that truly take no I/O away from `run_io_command`
- If it reproduces on a released binary, file a bug with the exact command line
Example fix
// before
struct CompileArgs { options: CompileOpts }
// after
struct CompileArgs { options: CompileOpts, #[clap(flatten)] io: IoArgs } Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
match cmd.io_args() { Some(io) => ..., None => anyhow::bail!("internal error: command does not take input & output") } Prevention
- Always attach IoArgs via clap flatten to every I/O subcommand
- Add a unit test iterating all Command variants asserting io_args() is Some where expected
When it happens
Trigger: A new/modified `Command` variant is dispatched through `run_io_command` -> `read_input` without providing `IoArgs`, so `Command::io_args()` matches None.
Common situations: Adding a new subcommand that forgets to populate `io_args` in the parser; refactoring the enum so a variant no longer carries input/output options.
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
- debug log was started, but it cannot be found after…
- Crate is not built with the `cli` feature enabled, or was…
- Currently `lex` only works with a single source, but found…
- Currently `annotate` only works with a single source, but…
- Currently `highlight` only works with a single source, but…
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/0834894b122159bc.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc/src/cli/mod.rs:535
}
match res {
Ok(r) => r?.as_bytes().to_vec(),
Err(payload) => panic::resume_unwind(payload),
}
}
_ => unreachable!("Other commands shouldn't reach `execute`"),
})
}
fn read_input(&mut self) -> Result<(SourceTree, String)> {
// Possibly this should be called by the relevant subcommands passing in
// `input`, rather than matching on them and grabbing `input` from
// `self`? But possibly if everything moves to `io_args`, then this is
// quite reasonable?
let io_args = self
.io_args()
.ok_or_else(|| anyhow!("internal error: command does not take input & output"))?;
let input = &mut io_args.input;
// Don't wait without a prompt when running `prqlc compile` —
// it's confusing whether it's waiting for input or not. This
// offers the prompt.
//
// See https://github.com/PRQL/prql/issues/3228 for details on us not
// yet using `input.is_tty()`.
if input.path() == Path::new("-") && std::io::stdin().is_terminal() {
#[cfg(unix)]
eprintln!("Enter PRQL, then press ctrl-d to compile:\n");
#[cfg(windows)]
eprintln!("Enter PRQL, then press ctrl-z to compile:\n");
}
let sources = read_files(input)?;
let main_path = io_args.main_path.clone().unwrap_or_default();View on GitHub (pinned to e164e249b9)