gastownhall/beads · error
failed to open file: %w
Error message
failed to open file: %w
What it means
parseMarkdownFile opens the validated path with os.Open; any open failure (permission denied, file vanished between validation and open, I/O error) is wrapped as "failed to open file: <os error>". This happens after path validation succeeded, so it usually reflects transient or permission issues rather than a missing file.
Source
Thrown at cmd/bd/markdown.go:271
scanner := bufio.NewScanner(file)
// Increase buffer size for large markdown files
const maxScannerBuffer = 1024 * 1024 // 1MB
buf := make([]byte, maxScannerBuffer)
scanner.Buffer(buf, maxScannerBuffer)
return scanner
}
func parseMarkdownFile(path string) ([]*IssueTemplate, error) {
// Validate and clean the file path
cleanPath, err := validateMarkdownPath(path)
if err != nil {
return nil, err
}
// #nosec G304 -- Path is validated by validateMarkdownPath which prevents traversal
file, err := os.Open(cleanPath)
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}
defer func() {
_ = file.Close() // Close errors on read-only operations are not actionable
}()
state := &markdownParseState{}
scanner := createMarkdownScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Check for H2 (new issue)
if matches := h2Regex.FindStringSubmatch(line); matches != nil {
state.handleH2Header(matches)
continue
}
// Check for H3 (section within issue)View on GitHub (pinned to 71377f2769)
Solutions
- Check file readability: `ls -l <file>` and `test -r <file>`; fix with chmod/chown or run as a user with access
- Re-run the command — the file may have been deleted mid-run by a prior step
- Verify the file is a regular readable file (not a broken symlink): `readlink -f <file>`
- Check mount health if the file is on NFS/network storage
Example fix
# before (unreadable file) -rw------- issues.md owned by root, bd runs as app user # after chmod 644 issues.md # or chown app:app issues.md
Defensive patterns
Strategy: try-catch
Validate before calling
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("pre-flight open failed: %w", err)
}
f.Close() Try / catch
if err := runImport(path); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {
// fix permissions or run as another user, then retry once
} else {
return err
}
} Prevention
- Ensure read permissions for the bd process user
- Avoid deleting/regenerating the file while import runs
- Keep files on local stable storage when possible
When it happens
Trigger: os.Open fails on an already-validated .md path: file deleted in a race between Stat and Open, read permission denied, or underlying device/I/O error (e.g. broken symlink surviving Stat, NFS stale handle).
Common situations: Files on network mounts going stale; another process deleting the temp file mid-run; restrictive umask/ownership after generation; container user lacking read access to mounted volume.
Related errors
- read rules directory: %w
- failed to read config.yaml: %w
- reading config: %w
- reading last_pull: %w
- dolt path is not executable
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c8ffbaf05e56563b.
Report an issue: GitHub.