wavetermdev/waveterm · error
reading from stdin: %w
Error message
reading from stdin: %w
What it means
Wraps any error from io.ReadAll(os.Stdin) when the `-` argument is used in `wsh ai`. Reading stdin failed at the OS level (I/O error, closed/broken pipe, EINTR, etc.). The original error is preserved via %w for errors.Is/As inspection.
Source
Thrown at cmd/wsh/cmd/wshcmd-ai.go:103
if len(args) > maxFileCount {
return fmt.Errorf("too many files (maximum %d files allowed)", maxFileCount)
}
for _, filePath := range args {
var data []byte
var fileName string
var mimeType string
var err error
if filePath == "-" {
if stdinUsed {
return fmt.Errorf("stdin (-) can only be used once")
}
stdinUsed = true
data, err = io.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("reading from stdin: %w", err)
}
fileName = "stdin"
mimeType = "text/plain"
} else {
fileInfo, err := os.Stat(filePath)
if err != nil {
return fmt.Errorf("accessing file %s: %w", filePath, err)
}
absPath, err := filepath.Abs(filePath)
if err != nil {
return fmt.Errorf("getting absolute path for %s: %w", filePath, err)
}
if fileInfo.IsDir() {
result, err := fileutil.ReadDir(filePath, 500)
if err != nil {
return fmt.Errorf("reading directory %s: %w", filePath, err)
}View on GitHub (pinned to a4447c1563)
Solutions
- Ensure stdin is actually provided: `cat file | wsh ai -` instead of a bare `wsh ai -` in a non-interactive shell.
- Check the upstream producer did not exit early; rerun the pipeline and fix the producing command first (inspect the wrapped error).
- If stdin may be closed, pass a file path instead of `-`.
- Retry on transient I/O errors (EINTR) — rerun the command.
Example fix
// before (in CI, stdin closed) $ wsh ai - // after $ cat report.txt | wsh ai - --message "summarize"
Defensive patterns
Strategy: try-catch
Validate before calling
if [ -t 0 ] || [ ! -r /dev/stdin ]; then echo "wsh ai '-' requires piped stdin, e.g. cat file | wsh ai -" >&2 exit 1 fi
Try / catch
if err := runAI(); err != nil {
var perr *os.PathError
if errors.As(err, &perr) && errors.Is(err, syscall.EPIPE) {
// upstream writer died; retry the pipeline after fixing the producer
} else {
return fmt.Errorf("stdin read failed: %w", err)
}
} Prevention
- Always pair `-` with an explicit pipe or redirect; never run `wsh ai -` bare in CI.
- Check the upstream command's exit status before consuming its output.
- Prefer passing a file path over `-` in non-interactive contexts.
When it happens
Trigger: `wsh ai -` where stdin is closed or not connected (no pipe/redirection in a non-tty context), the upstream writer process died mid-stream (broken pipe), or an OS I/O error (disk/device failure, interrupted read) occurs during the read.
Common situations: CI jobs invoking `wsh ai -` without piping anything and stdin closed; `someproc | wsh ai -` where someproc crashed; running under a supervisor that detached stdin.
Related errors
- failed to read JWT token from stdin: %w
- reading stdin: %w
- stdin (-) can only be used once
- reading input: %w
- error writing to file %s: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/16e6ebe75e954da9.
Report an issue: GitHub.