run-llama/liteparse · error · std::io::Error

no data on stdin (input `-` expects a document piped in…

Error message

no data on stdin (input `-` expects a document piped in, e.g. `curl … | lit parse -`)

What it means

The Python-binding CLI (`lit` from the PyPI/native package) reads the whole document from stdin when the input argument is `-`, and raises `UnexpectedEof` if zero bytes were received. This guards against running `lit parse -` in a terminal with nothing piped in, which would otherwise produce a confusing parser failure. The message explicitly shows the expected usage pattern.

Solutions

  1. Pipe actual document bytes: `curl -sL https://example.com/doc.pdf | lit parse -`
  2. Check the upstream command's exit status before the pipe (`set -o pipefail` in bash)
  3. If the document is on disk, pass the file path directly instead of `-`
  4. Verify the source URL/file actually contains data (`curl -sL <url> | wc -c`)

Example fix

// before
lit parse -
// after
curl -fsSL https://example.com/report.pdf | lit parse -
# or, from a file:
lit parse ./report.pdf
Defensive patterns

Strategy: validation

Validate before calling

# before running: lit parse -
data=$(curl -fsSL "$URL" | tee /dev/stderr | wc -c)
[ "$data" -gt 0 ] || { echo "upstream produced no data" >&2; exit 1; }

Try / catch

if ! curl -fsSL "$URL" | lit parse -; then
  echo "pipe failed: check curl output/exit status" >&2
fi
# with pipefail:
set -o pipefail

Prevention

When it happens

Trigger: Running `lit parse -` (or equivalent subcommand with `-` as input) without piping any data: bare invocation in a terminal, a failed/silent upstream command in the pipe (e.g. `curl` returned nothing), or stdin redirected from an empty file (`< empty.pdf`).

Common situations: Copy-pasting the `curl … | lit parse -` example where curl failed or printed an error page to stderr only, forgetting the pipe and typing the command interactively, or an empty file produced by a failed download.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of run-llama/liteparse@22d2dd8cd7 (2026-09-08). Data as JSON: /api/errors/5c815a64ac68778f. Report an issue: GitHub.

Appendix: source

Thrown at crates/liteparse-python/src/cli.rs:262

    match s.to_lowercase().as_str() {
        "off" | "none" => Ok(ImageMode::Off),
        "placeholder" => Ok(ImageMode::Placeholder),
        "embed" => Ok(ImageMode::Embed),
        _ => Err(format!(
            "unknown image-mode '{}', expected 'off', 'placeholder', or 'embed'",
            s
        )),
    }
}

/// Read all bytes from stdin, used when the input path is `-` (e.g. a piped
/// document: `curl -sL … | lit parse -`).
fn read_stdin_bytes() -> Result<Vec<u8>, std::io::Error> {
    use std::io::Read;
    let mut bytes = Vec::new();
    std::io::stdin().lock().read_to_end(&mut bytes)?;
    if bytes.is_empty() {
        return Err(std::io::Error::new(
            std::io::ErrorKind::UnexpectedEof,
            "no data on stdin (input `-` expects a document piped in, e.g. `curl … | lit parse -`)",
        ));
    }
    Ok(bytes)
}

/// Run the CLI with the given args (typically from sys.argv).
pub fn run_cli(args: Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
    let cli = Cli::parse_from(args);
    let rt = tokio::runtime::Runtime::new()?;

    match cli.command {
        Commands::Parse(cmd) => {
            let format = parse_output_format(&cmd.format)?;
            let image_mode = parse_image_mode(&cmd.image_mode)?;
            let mut config = LiteParseConfig {
                ocr_language: cmd.ocr_language,

View on GitHub (pinned to 22d2dd8cd7)