{"record":{"id":"e6b2d20dd4be2686","repo":"larksuite/cli","slug":"stdin-is-not-available","errorCode":null,"errorMessage":"stdin is not available","messagePattern":"stdin is not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmdutil/resolve.go","lineNumber":35,"sourceCode":"//   - \"@<path>\" → read all bytes from the file at <path> via fileIO\n//   - \"@@...\"   → strip leading @ (escape for a literal @-prefixed value)\n//   - \"'...'\"   → strip surrounding single quotes (Windows cmd.exe compatibility)\n//   - other     → return as-is\n//\n// fileIO is required for \"@<path>\" inputs and goes through path validation\n// (SafeInputPath); pass nil only when callers know \"@\" inputs are not possible.\n//\n// Allows callers to bypass shell quoting issues (especially Windows PowerShell 5)\n// by reading JSON from a file (@path) or piping via stdin (-).\nfunc ResolveInput(raw string, stdin io.Reader, fileIO fileio.FileIO) (string, error) {\n\tif raw == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\t// stdin\n\tif raw == \"-\" {\n\t\tif stdin == nil {\n\t\t\treturn \"\", fmt.Errorf(\"stdin is not available\")\n\t\t}\n\t\tdata, err := io.ReadAll(stdin)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to read stdin: %w\", err)\n\t\t}\n\t\ts := strings.TrimSpace(string(data))\n\t\tif s == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"stdin is empty (did you forget to pipe input?)\")\n\t\t}\n\t\treturn s, nil\n\t}\n\n\t// escape: @@... → literal @... (no file read)\n\tif strings.HasPrefix(raw, \"@@\") {\n\t\treturn raw[1:], nil\n\t}\n\n\t// file: @path","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/cmdutil/resolve.go#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (no stdin attached)\nlark-cli service call ... --body -\n// after\necho '{\"k\":\"v\"}' | lark-cli service call ... --body -\n# or\nlark-cli service call ... --body @body.json","handlingStrategy":"validation","validationCode":"if bodyFlag == \"-\" && stdinUnavailable {\n\tbodyFlag = \"@body.json\" // fall back to file input\n}","typeGuard":"func stdinAvailable(r io.Reader) bool { return r != nil }","tryCatchPattern":"val, err := cmdutil.ResolveInput(raw, stdin, fileIO)\nif err != nil {\n\tif strings.Contains(err.Error(), \"stdin is not available\") {\n\t\treturn fmt.Errorf(\"pass a file via @path or pipe input to stdin: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["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."],"tags":["go","stdin","cli-input"],"backgroundTag":"stdin-unavailable","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}