gastownhall/beads · error

fs: WriteProjectGitignore: patterns not configured

Error message

fs: WriteProjectGitignore: patterns not configured

What it means

WriteProjectGitignore merges bd's required patterns into the project .gitignore. This sentinel error means templates.ProjectGitignorePatterns is empty, so there is no pattern set to ensure. Like the other template errors, it indicates faulty repository construction rather than a disk problem.

Source

Thrown at internal/storage/domain/fs/beads.go:148

		trimmed := strings.TrimSpace(line)
		if trimmed == "" || strings.HasPrefix(trimmed, "#") || have[trimmed] {
			continue
		}
		missing = append(missing, trimmed)
	}
	return missing
}

func (r *beadsDirFSRepositoryImpl) BeadsGitignoreExists(ctx context.Context) (bool, error) {
	return fileExists(filepath.Join(r.beadsDir, ".gitignore"), "fs: BeadsGitignoreExists")
}

func (r *beadsDirFSRepositoryImpl) WriteProjectGitignore(ctx context.Context) error {
	if r.workDir == "" {
		return fmt.Errorf("fs: WriteProjectGitignore: workDir not set")
	}
	if len(r.templates.ProjectGitignorePatterns) == 0 {
		return fmt.Errorf("fs: WriteProjectGitignore: patterns not configured")
	}
	path := filepath.Join(r.workDir, ".gitignore")
	// #nosec G304 -- path joined under bound workDir
	existing, err := os.ReadFile(path)
	if err != nil && !errors.Is(err, os.ErrNotExist) {
		return fmt.Errorf("fs: WriteProjectGitignore: read: %w", err)
	}

	var toAdd []string
	for _, pattern := range r.templates.ProjectGitignorePatterns {
		if !containsLine(existing, pattern) {
			toAdd = append(toAdd, pattern)
		}
	}
	if len(toAdd) == 0 {
		return nil
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use the standard repository constructor so default ProjectGitignorePatterns are loaded
  2. If supplying custom patterns, pass a non-empty slice of pattern strings
  3. Check that embedded template assets are present in the build
  4. Upgrade/repair local modifications that cleared the template configuration

Example fix

// before
tpl := Templates{} // ProjectGitignorePatterns empty
r := fsrepo.New(fsrepo.WithTemplates(tpl))
r.WriteProjectGitignore(ctx) // patterns not configured
// after
tpl := fsrepo.DefaultTemplates() // includes ProjectGitignorePatterns
r := fsrepo.New(fsrepo.WithTemplates(tpl))
r.WriteProjectGitignore(ctx)
Defensive patterns

Strategy: validation

Validate before calling

if len(projectGitignorePatterns) == 0 {
	return errors.New("no ProjectGitignorePatterns provided; use fsrepo.DefaultTemplates()")
}
repo.WriteProjectGitignore(ctx)

Type guard

func hasProjectPatterns(t Templates) bool { return len(t.ProjectGitignorePatterns) > 0 }

Try / catch

if err := repo.WriteProjectGitignore(ctx); err != nil {
	if strings.Contains(err.Error(), "patterns not configured") {
		return fmt.Errorf("template set empty; rebuild repo with default templates")
	}
	return err
}

Prevention

When it happens

Trigger: Calling WriteProjectGitignore on a repository constructed without the project-gitignore pattern list (zero-length ProjectGitignorePatterns).

Common situations: Manual/zero-value struct construction in tests; a custom template source that returns an empty pattern slice; build/embed misconfiguration dropping the default patterns.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/314b9fccb9241c57. Report an issue: GitHub.