astral-sh/ruff · error

Can only write to stdout when formatting from stdin, but you

Error message

Can only write to stdout when formatting from stdin, but you asked for {:?}

What it means

This is the standalone debug binary of the Python formatter. When no files are given, it formats stdin and writes the result to stdout; a non-stdout `--emit` mode is then meaningless, so `main` bails with this anyhow error naming the requested emit mode.

Source

Thrown at crates/ruff_python_formatter/src/main.rs:22

use anyhow::{Context, Result, bail};
use clap::Parser as ClapParser;

use ruff_python_formatter::cli::{Cli, Emit, format_and_debug_print};

/// Read a `String` from `stdin`.
fn read_from_stdin() -> Result<String> {
    let mut buffer = String::new();
    io::stdin().lock().read_to_string(&mut buffer)?;
    Ok(buffer)
}

fn main() -> Result<()> {
    let cli: Cli = Cli::parse();

    if cli.files.is_empty() {
        if !matches!(cli.emit, None | Some(Emit::Stdout)) {
            bail!(
                "Can only write to stdout when formatting from stdin, but you asked for {:?}",
                cli.emit
            );
        }
        let source = read_from_stdin()?;
        // It seems reasonable to give this a dummy name
        let formatted = format_and_debug_print(&source, &cli, Path::new("stdin.py"))?;
        if cli.check {
            if formatted == source {
                return Ok(());
            }
            bail!("Content not correctly formatted")
        }
        stdout().lock().write_all(formatted.as_bytes())?;
    } else {
        for file in &cli.files {
            let source = fs::read_to_string(file)
                .with_context(|| format!("Could not read {}: ", file.display()))?;

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Drop the `--emit` flag when piping source via stdin
  2. Pass actual file paths as arguments if you want non-stdout behavior from the normal ruff CLI instead
  3. Use the main `ruff` binary, which supports `--emit` for file-based runs

Example fix

// before
ruff_python_formatter --emit json < file.py
// after
ruff_python_formatter < file.py
Defensive patterns

Strategy: validation

Validate before calling

# shell check before invoking
if [ -t 0 ] && [ $# -eq 0 ]; then echo "stdin expected: drop --emit"; fi

Prevention

When it happens

Trigger: Running `ruff_python_formatter` (dev binary) with no file arguments while passing `--emit json` (or any `Emit` variant other than stdout).

Common situations: Copying emit flags from the main `ruff format` CLI into the formatter debug binary; scripting the debug binary expecting JSON output from stdin.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/df467c4eca861c39. Report an issue: GitHub.