{"record":{"id":"dfdaf47938de63a0","repo":"larksuite/cli","slug":"failed-to-read-stdin-w","errorCode":null,"errorMessage":"failed to read stdin: %w","messagePattern":"failed to read stdin: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmdutil/resolve.go","lineNumber":39,"sourceCode":"//\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\n\tif strings.HasPrefix(raw, \"@\") {\n\t\tpath := strings.TrimSpace(raw[1:])\n\t\tif path == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"file path cannot be empty after @\")","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/cmdutil/resolve.go#L21-L57","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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 \"-\""],"exampleFix":"// before\necho x | broken-producer | lark-cli cmd --body -\n// after\nproducer-ok | lark-cli cmd --body -","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"val, err := cmdutil.ResolveInput(\"-\", fileIO, os.Stdin)\nif err != nil {\n    var wrapped interface{ Unwrap() error }\n    if errors.As(err, &wrapped) { log.Printf(\"stdin read cause: %v\", errors.Unwrap(err)) }\n    return err\n}","preventionTips":["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"],"tags":["stdin","io","cli"],"backgroundTag":"stdin-read-failed","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"}