larksuite/cli · error
stdin is not available
Error message
stdin is not available
What it means
ResolveInput in internal/cmdutil/resolve.go maps the special flag value '-' to 'read the body from stdin'. If the caller passed a nil stdin io.Reader (a context where stdin was not wired up), there is nothing to read, so it fails fast with 'stdin is not available' instead of panicking on a nil reader.
Source
Thrown at internal/cmdutil/resolve.go:35
// - "@<path>" → read all bytes from the file at <path> via fileIO
// - "@@..." → strip leading @ (escape for a literal @-prefixed value)
// - "'...'" → strip surrounding single quotes (Windows cmd.exe compatibility)
// - other → return as-is
//
// 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: @pathView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Pipe the input in, e.g. `echo '{...}' | lark-cli ...` or redirect: `cmd - < body.json`.
- Use the '@<path>' form to read the body from a file instead of stdin.
- If invoking programmatically, pass a non-nil io.Reader (strings.Reader or os.Stdin) to ResolveInput.
Example fix
// before (no stdin attached)
lark-cli service call ... --body -
// after
echo '{"k":"v"}' | lark-cli service call ... --body -
# or
lark-cli service call ... --body @body.json Defensive patterns
Strategy: validation
Validate before calling
if bodyFlag == "-" && stdinUnavailable {
bodyFlag = "@body.json" // fall back to file input
} Type guard
func stdinAvailable(r io.Reader) bool { return r != nil } Try / catch
val, err := cmdutil.ResolveInput(raw, stdin, fileIO)
if err != nil {
if strings.Contains(err.Error(), "stdin is not available") {
return fmt.Errorf("pass a file via @path or pipe input to stdin: %w", err)
}
return err
} Prevention
- In scripts and CI, always pipe or redirect input when using '-', or prefer the '@file' form.
- In programmatic use, never pass nil stdin unless '-' cannot appear in raw values.
- Document '-' stdin behavior in command help so users know a pipe is required.
- Prefer '@<path>' for non-interactive automation; reserve '-' for interactive pipelines.
When it happens
Trigger: Passing '-' as a raw flag value (e.g. a body/payload flag) through ParseOptionalBody/ParseJSONMap where ResolveInput received stdin == nil — typically embedded CLI use without os.Stdin, or an environment with stdin detached.
Common situations: Running the CLI from CI with stdin closed while using '-' for the body flag; calling the library function directly with nil stdin; schedulers that detach standard input.
Related errors
- Invalid column: {column!r}
- Invalid column index: {index}
- anchor outside sheet: {position!r}
- invalid chart size: {size!r}
- Missing row_count/column_count for sheet {sheet_title(sheet)
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/e6b2d20dd4be2686.
Report an issue: GitHub.