gastownhall/beads · error
failed to read .gitignore: %w
Error message
failed to read .gitignore: %w
What it means
EnsureProjectGitignore reads the project's existing .gitignore so it can append only missing patterns. If os.ReadFile fails with any error other than NotExist (which is treated as 'no file yet'), it wraps and returns this error. It signals an unexpected filesystem problem, not a missing file.
Source
Thrown at cmd/bd/doctor/gitignore.go:774
Status: StatusOK,
Message: "Dolt and credential files excluded",
}
}
// EnsureProjectGitignore adds .dolt/, *.db, and .beads-credential-key patterns
// to the project-root .gitignore if they are not already present. Creates the
// file if it doesn't exist. This prevents users from accidentally committing
// Dolt database files or the credential encryption key.
// repoPath is the project root directory.
func EnsureProjectGitignore(repoPath string) error {
gitignorePath := filepath.Join(repoPath, ".gitignore")
var existingContent string
// #nosec G304 -- path is hardcoded
if content, err := os.ReadFile(gitignorePath); err == nil {
existingContent = string(content)
} else if !os.IsNotExist(err) {
return fmt.Errorf("failed to read .gitignore: %w", err)
}
var toAdd []string
for _, pattern := range ProjectGitignorePatterns {
if !containsGitignorePattern(existingContent, pattern) {
toAdd = append(toAdd, pattern)
}
}
if len(toAdd) == 0 {
return nil // All patterns already present
}
newContent := existingContent
if len(newContent) > 0 && !strings.HasSuffix(newContent, "\n") {
newContent += "\n"
}
View on GitHub (pinned to 71377f2769)
Solutions
- Check permissions: ls -la .gitignore and chmod u+r (or chown) so the running user can read it.
- If .gitignore is a directory, remove or rename it (mv .gitignore .gitignore.bak) and re-run bd doctor --fix.
- Run inside the correct repo directory; a wrong cwd can point gitignorePath at an unusable path.
- If on a network/odd filesystem, copy the repo locally and retry.
Example fix
// before $ bd doctor --fix Error: failed to read .gitignore: open /repo/.gitignore: is a directory // after $ mv -f .gitignore .gitignore.bak $ bd doctor --fix ✓ .gitignore updated
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(gitignorePath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("precheck: cannot stat .gitignore: %w", err)
}
if info != nil && info.IsDir() {
return fmt.Errorf("precheck: .gitignore is a directory")
} Try / catch
if _, err := doctor.EnsureProjectGitignore(dir); err != nil {
var perr *fs.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.EACCES) {
// handle permission problem (chown/chmod or elevate)
}
return err
} Prevention
- Run bd doctor as a user with read access to the repo.
- Never replace .gitignore with a directory or broken symlink.
- Check file health (ls -la .gitignore) before automated fixes on odd filesystems.
When it happens
Trigger: os.ReadFile(gitignorePath) returns an error and !os.IsNotExist(err) — e.g. a .gitignore path that is a directory, or a permission-denied read.
Common situations: .gitignore exists but the process lacks read permission; .gitignore is actually a directory (often from a bad checkout or symlink); filesystem/ACL issues on network mounts; SELinux or sandbox policies blocking reads in CI containers.
Related errors
- ensure .beads/.gitignore: %w
- read .beads/.gitignore: %w
- failed to write .gitignore: %w
- fs: WriteBeadsGitignore: %w
- fs: WriteBeadsGitignore: read: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/6498d4f6a2670bc4.
Report an issue: GitHub.