gastownhall/beads · error
failed to open file: %w
Error message
failed to open file: %w
What it means
readBodyFile loads body text for command flags (--description-file, --design-file, --reason-file, etc.) from a file path or '-' for stdin. This error wraps os.Open failures: the file could not be opened at all. It is a straightforward file-path/permission problem surfaced when the CLI tries to read user-supplied body content.
Source
Thrown at cmd/bd/flags.go:198
v, _ := cmd.Flags().GetString("design")
return v, true, nil
}
return "", false, nil
}
// readBodyFile reads the description content from a file.
// If filePath is "-", reads from stdin.
func readBodyFile(filePath string) (string, error) {
var reader io.Reader
if filePath == "-" {
reader = os.Stdin
} else {
// #nosec G304 - filePath comes from user flag, validated by caller
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()
reader = file
}
content, err := io.ReadAll(reader)
if err != nil {
return "", fmt.Errorf("failed to read file: %w", err)
}
return string(content), nil
}
// textSources names the places a command can take body text from: stdin, a
// file path, an explicit text flag, then positional args. A non-nil stdin
// means --stdin was given. flagName names the text flag (e.g. "--response")
// in conflict errors and always accompanies flagText. flagSet marks the text
// flag as explicitly passed (cobra's Changed), so an empty flag value stillView on GitHub (pinned to 71377f2769)
Solutions
- Verify the path exists and is readable: ls -l <path>; correct typos and use an absolute path if unsure
- Check that you didn't pass a directory instead of a file
- Fix file permissions (chmod/chown) or run from a context/user that can read it
- If the text is short or generated, pipe it via stdin with '-' or pass it inline instead of via a file
Example fix
// before: path from an unset variable bd create "T" --description-file="$NOTES_FILE" // failed to open file: open : no such file or directory // after: guard the variable before invoking [ -n "$NOTES_FILE" ] && [ -f "$NOTES_FILE" ] && bd create "T" --description-file="$NOTES_FILE"
Defensive patterns
Strategy: validation
Validate before calling
path := filePath
if path != "-" {
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("body file not accessible: %w", err)
}
if info.IsDir() {
return fmt.Errorf("body file is a directory: %s", path)
}
f, err := os.Open(path)
if err != nil { return err }
f.Close()
} Type guard
func readableFile(path string) bool {
if path == "-" { return true }
f, err := os.Open(path)
if err != nil { return false }
f.Close()
return true
} Try / catch
content, err := readBodyFile(flagPath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("--description-file: no such file: %s", flagPath)
}
if errors.Is(err, os.ErrPermission) {
return fmt.Errorf("--description-file: permission denied: %s", flagPath)
}
return err
} Prevention
- Quote and verify file-flag paths in shell scripts; fail on unset variables (${VAR:?})
- Use absolute paths or run from the expected working directory
- Pass a regular file, not a directory
- Use '-' with stdin (or inline text) when content is generated rather than stored
When it happens
Trigger: Passing --description-file/--design-file/--reason-file with a path that does not exist, is a directory, or lacks read permission; a typo'd path; using '-' when stdin is closed/unavailable (less common; that path bypasses os.Open).
Common situations: Shell variable empty or unset so the flag receives a truncated path; running from a different working directory than assumed; file deleted between tab-completion and execution; permissions tightened by sandboxed CI environments.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- failed to read file: %w
- cannot use both --pull-only and --push-only
- %w (--prefer-local, --prefer-ado, --prefer-newer)
- %s
- open batch file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8da86c57b8c1b807.
Report an issue: GitHub.