rtk-ai/rtk · error
Failed to read stdin
Error message
Failed to read stdin: {} What it means
In non-passthrough mode, `pipe_cmd::run` reads up to RAW_CAP+1 bytes from stdin via `Read::take(...).read_to_string(&mut buf)`. Two failure modes surface here: the read itself errors (mapped to `Failed to read stdin: {}` at line 267), and, if more than RAW_CAP bytes arrived, a subsequent `bail!("stdin exceeds {} byte limit", RAW_CAP)` protects rtk from oversized payloads. Both exist because pipe filters operate on bounded in-memory buffers.
Solutions
- Ensure input is valid UTF-8 text (e.g. `iconv -f ... -t utf-8` first) — read_to_string fails on invalid bytes.
- Reduce input below rtk's stdin size cap: pre-filter/truncate with `head -c`, or use `rtk proxy` for unbounded raw output.
- Verify the stdin source is readable (`test -r file` before redirecting) and not a device that errors on read.
- If the size limit is the blocker, split input into chunks or process with standard tools instead of `rtk pipe`.
Example fix
// before (shell) cat binary.dump | rtk pipe --filter text // after (shell) # decode to UTF-8 and cap size before piping iconv -f latin1 -t utf-8 binary.dump | head -c 1048576 | rtk pipe --filter text
Defensive patterns
Strategy: validation
Validate before calling
# check size and UTF-8 before piping into rtk pipe
size=$(stat -c%s input.txt)
limit=1048576 # match rtk's RAW_CAP
if [ "$size" -gt "$limit" ]; then echo "input too large for rtk pipe" >&2; exit 1; fi
iconv -f utf-8 -t utf-8 input.txt >/dev/null 2>&1 || { echo "input is not valid UTF-8" >&2; exit 1; } Try / catch
if ! rtk pipe --filter text < input.txt; then echo 'fell back: use rtk proxy or split the input' >&2 rtk proxy cat input.txt fi
Prevention
- Check input size against rtk's stdin cap before piping.
- Convert non-UTF-8 input with iconv/dos2unix first.
- Use `rtk proxy` for arbitrarily large or binary payloads.
- Sanity-check stdin sources (regular readable files, not devices).
When it happens
Trigger: Piping data into `rtk pipe` (without --passthrough) when: (a) stdin read fails (invalid UTF-8 for read_to_string, or an I/O error) → this message; (b) input exceeds the RAW_CAP byte cap → the adjacent size-limit bail. Raised from `pipe_cmd::run` at src/cmds/system/pipe_cmd.rs:267.
Common situations: Piping binary data (non-UTF-8) into `rtk pipe`; piping very large files/logs that exceed rtk's stdin byte cap; stdin from a special file or device that errors mid-read; encoding mismatches after locale changes.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19).
Data as JSON: /api/errors/229f9a4cee75fd30.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmds/system/pipe_cmd.rs:267
|_| {
eprintln!("[rtk] warning: filter panicked — passing through raw output");
input.to_string()
},
)
}
pub fn run(filter_name: Option<&str>, passthrough: bool) -> Result<()> {
if passthrough {
std::io::copy(&mut std::io::stdin(), &mut std::io::stdout())
.map_err(|e| anyhow::anyhow!("Failed to relay stdin: {}", e))?;
return Ok(());
}
let mut buf = String::new();
std::io::stdin()
.take((RAW_CAP + 1) as u64)
.read_to_string(&mut buf)
.map_err(|e| anyhow::anyhow!("Failed to read stdin: {}", e))?;
if buf.len() > RAW_CAP {
anyhow::bail!("stdin exceeds {} byte limit", RAW_CAP);
}
let filter_fn = match filter_name {
Some(name) => resolve_filter(name).ok_or_else(|| {
anyhow::anyhow!(
"Unknown filter '{}'. Available: cargo-test, pytest, go-test, go-build, \
ctest, tsc, vitest, grep, rg, find, fd, git-log, git-diff, git-status, \
log, mypy, ruff-check, ruff-format, sqlfluff-lint, prettier, phpunit, pest, \
paratest, php-test, ecs, phpstan, pint",
name
)
})?,
None => auto_detect_filter(&buf),
};
let output = apply_filter(filter_fn, &buf);View on GitHub (pinned to 0924356b4c)