larksuite/cli · error
failed to read stdin: %w
Error message
failed to read stdin: %w
What it means
ResolveInput reads piped stdin when the input value is the literal "-". This error wraps an underlying I/O failure returned by io.ReadAll on the stdin reader, preserving the cause via %w. It signals the pipe/reader broke mid-read rather than an empty or missing input.
Source
Thrown at internal/cmdutil/resolve.go:39
//
// fileIO is required for "@<path>" inputs and goes through path validation
// (SafeInputPath); pass nil only when callers know "@" inputs are not possible.
//
// Allows callers to bypass shell quoting issues (especially Windows PowerShell 5)
// by reading JSON from a file (@path) or piping via stdin (-).
func ResolveInput(raw string, stdin io.Reader, fileIO fileio.FileIO) (string, error) {
if raw == "" {
return "", nil
}
// stdin
if raw == "-" {
if stdin == nil {
return "", fmt.Errorf("stdin is not available")
}
data, err := io.ReadAll(stdin)
if err != nil {
return "", fmt.Errorf("failed to read stdin: %w", err)
}
s := strings.TrimSpace(string(data))
if s == "" {
return "", fmt.Errorf("stdin is empty (did you forget to pipe input?)")
}
return s, nil
}
// escape: @@... → literal @... (no file read)
if strings.HasPrefix(raw, "@@") {
return raw[1:], nil
}
// file: @path
if strings.HasPrefix(raw, "@") {
path := strings.TrimSpace(raw[1:])
if path == "" {
return "", fmt.Errorf("file path cannot be empty after @")View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check the wrapped cause (errors.Unwrap / %v) to identify the underlying I/O error
- Fix the pipeline so the producer stays alive until the CLI finishes reading stdin
- Verify stdin is a readable pipe, not a closed or write-only descriptor
- If no input is intended, pass a literal value or @file instead of "-"
Example fix
// before echo x | broken-producer | lark-cli cmd --body - // after producer-ok | lark-cli cmd --body -
Defensive patterns
Strategy: try-catch
Try / catch
val, err := cmdutil.ResolveInput("-", fileIO, os.Stdin)
if err != nil {
var wrapped interface{ Unwrap() error }
if errors.As(err, &wrapped) { log.Printf("stdin read cause: %v", errors.Unwrap(err)) }
return err
} Prevention
- Keep the pipeline producer alive until the CLI exits
- Check the unwrapped cause to distinguish closed pipe vs I/O failure
- Prefer @file for large or pre-existing payloads
- Test stdin paths with a failing-reader harness
When it happens
Trigger: Calling ParseOptionalBody or ParseJSONMap with a flag value of "-" while the process stdin reader returns a read error (e.g. closed pipe, I/O error on the underlying fd, reader supplied via stdin param fails).
Common situations: Upstream process in a shell pipeline exited early closing the pipe; running under a environment where stdin is a failing pseudo-device; custom FileIO/test harness injecting a failing reader.
Related errors
- failed to read input: %w
- input terminated unexpectedly (EOF)
- stdin is empty (did you forget to pipe input?)
- invalid chart size: {size!r}
- --header-scan-rows must be at least 1
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/dfdaf47938de63a0.
Report an issue: GitHub.