larksuite/cli · error
stdin is empty (did you forget to pipe input?)
Error message
stdin is empty (did you forget to pipe input?)
What it means
ResolveInput trims whitespace from stdin data and rejects it when nothing remains. The library throws this so commands never silently submit an empty body caused by an unplumbed or accidentally empty pipe. The message is a hint that the user likely forgot to pipe input.
Source
Thrown at internal/cmdutil/resolve.go:43
// 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 @")
}
data, err := ReadInputFile(fileIO, path)
if err != nil {
return "", errView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Pipe the payload into the command, e.g. echo '{...}' | lark-cli cmd --body -
- Verify the upstream producer actually emits non-empty output
- Use @path-to-file instead of "-" if the payload already exists on disk
- Quote/escape correctly so "-" is passed as the flag value, not consumed by the shell
Example fix
// before
lark-cli im message create --body -
// after
echo '{"receive_id":"ou_x","content":"{}"}' | lark-cli im message create --body - Defensive patterns
Strategy: validation
Validate before calling
// before running with "-":
if [ -t 0 ]; then echo "stdin is a TTY: nothing piped"; exit 1; fi
# or in Go:
fi, _ := os.Stdin.Stat(); if fi.Mode()&os.ModeCharDevice != 0 { /* no piped input */ } Try / catch
if err != nil && strings.Contains(err.Error(), "stdin is empty") {
fmt.Fprintln(os.Stderr, "hint: pipe the JSON body, e.g. echo '{...}' | cmd --body -")
} Prevention
- Always pair "-" with a producer in shell one-liners
- Check upstream command exit status and output size before piping
- Use @file when the payload is static
- Verify CI steps actually emit output
When it happens
Trigger: Passing "-" as the input to ParseOptionalBody/ParseJSONMap while running the command without piping anything (or piping only whitespace/newlines) into stdin.
Common situations: Forgetting the echo/cat pipe in a shell one-liner; piping an empty file; copying a documented pipeline but omitting the producer; CI step where the upstream step produced no output.
Related errors
- failed to read input: %w
- input terminated unexpectedly (EOF)
- failed to read stdin: %w
- --header-scan-rows must be at least 1
- +csv-get truncated the requested range at {source_range}; na
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/8415a2fe292ecd88.
Report an issue: GitHub.