{"record":{"id":"d5a98594a072f3b1","repo":"gastownhall/beads","slug":"failed-to-read-file-w","errorCode":null,"errorMessage":"failed to read file: %w","messagePattern":"failed to read file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/flags.go","lineNumber":206,"sourceCode":"// If filePath is \"-\", reads from stdin.\nfunc readBodyFile(filePath string) (string, error) {\n\tvar reader io.Reader\n\n\tif filePath == \"-\" {\n\t\treader = os.Stdin\n\t} else {\n\t\t// #nosec G304 - filePath comes from user flag, validated by caller\n\t\tfile, err := os.Open(filePath)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to open file: %w\", err)\n\t\t}\n\t\tdefer file.Close()\n\t\treader = file\n\t}\n\n\tcontent, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read file: %w\", err)\n\t}\n\n\treturn string(content), nil\n}\n\n// textSources names the places a command can take body text from: stdin, a\n// file path, an explicit text flag, then positional args. A non-nil stdin\n// means --stdin was given. flagName names the text flag (e.g. \"--response\")\n// in conflict errors and always accompanies flagText. flagSet marks the text\n// flag as explicitly passed (cobra's Changed), so an empty flag value still\n// counts as a source — like a blank positional — rather than as absent.\ntype textSources struct {\n\tstdin      io.Reader\n\tfilePath   string\n\tflagText   string\n\tflagName   string\n\tflagSet    bool\n\tpositional []string","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/flags.go#L188-L224","documentation":"readBodyFile wraps io.ReadAll failures with this error: the file (or stdin pipe) was opened successfully but reading its contents failed. This is rarer than open failures and typically indicates I/O problems — a failing disk, a broken pipe on stdin, or reading a special/character device that errors mid-read.","triggerScenarios":"Passing a file flag pointing at a special file (e.g. /dev files) that errors on read; disk or network filesystem failure mid-read; stdin ('-') receiving a broken pipe or being closed by the upstream process; permission changes after open on some filesystems.","commonSituations":"Piping output from a command that died mid-stream (broken pipe into `bd ... --description-file=-`); reading files on a disconnected NFS/network mount; hardware/disk errors on the volume holding the file.","solutions":["If using '-' with a pipe, check that the upstream command completed successfully (its exit status) and re-run the pipeline","Retry reading the file with cat <path> to confirm the file itself is readable; check dmesg/disk health if reads fail system-wide","Copy the file to local disk if it lives on a flaky network mount, then retry the bd command","Pass the content inline or via an editor instead of a file if the source is unreliable"],"exampleFix":"// before: upstream failure silently truncates the pipe\n./gen-notes | bd update bd-1 --description-file=-   // failed to read file: read ...: broken pipe\n// after: propagate upstream failure before feeding bd\nnotes=$(./gen-notes) && printf '%s' \"$notes\" | bd update bd-1 --description-file=-","handlingStrategy":"try-catch","validationCode":"path := filePath\nif path != \"-\" {\n    if _, err := os.ReadFile(path); err != nil {\n        return fmt.Errorf(\"body file not readable: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"content, err := readBodyFile(flagPath)\nif err != nil {\n    var perr *os.PathError\n    if errors.As(err, &perr) {\n        return fmt.Errorf(\"reading body %s: %v\", flagPath, perr.Err)\n    }\n    return err\n}","preventionTips":["Check the exit status of upstream commands piping into '-' before running bd","Keep files on reliable local storage; avoid flaky network mounts for flag-file input","Test with `cat <path> > /dev/null` if reads fail to isolate disk vs. CLI issues","Prefer inline text or stdin for ephemeral/generated content instead of special files"],"tags":["go","cli","file-io","stdin"],"backgroundTag":"file-read-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}