{"record":{"id":"314b9fccb9241c57","repo":"gastownhall/beads","slug":"fs-writeprojectgitignore-patterns-not-configured","errorCode":null,"errorMessage":"fs: WriteProjectGitignore: patterns not configured","messagePattern":"fs: WriteProjectGitignore: patterns not configured","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/fs/beads.go","lineNumber":148,"sourceCode":"\t\ttrimmed := strings.TrimSpace(line)\n\t\tif trimmed == \"\" || strings.HasPrefix(trimmed, \"#\") || have[trimmed] {\n\t\t\tcontinue\n\t\t}\n\t\tmissing = append(missing, trimmed)\n\t}\n\treturn missing\n}\n\nfunc (r *beadsDirFSRepositoryImpl) BeadsGitignoreExists(ctx context.Context) (bool, error) {\n\treturn fileExists(filepath.Join(r.beadsDir, \".gitignore\"), \"fs: BeadsGitignoreExists\")\n}\n\nfunc (r *beadsDirFSRepositoryImpl) WriteProjectGitignore(ctx context.Context) error {\n\tif r.workDir == \"\" {\n\t\treturn fmt.Errorf(\"fs: WriteProjectGitignore: workDir not set\")\n\t}\n\tif len(r.templates.ProjectGitignorePatterns) == 0 {\n\t\treturn fmt.Errorf(\"fs: WriteProjectGitignore: patterns not configured\")\n\t}\n\tpath := filepath.Join(r.workDir, \".gitignore\")\n\t// #nosec G304 -- path joined under bound workDir\n\texisting, err := os.ReadFile(path)\n\tif err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\treturn fmt.Errorf(\"fs: WriteProjectGitignore: read: %w\", err)\n\t}\n\n\tvar toAdd []string\n\tfor _, pattern := range r.templates.ProjectGitignorePatterns {\n\t\tif !containsLine(existing, pattern) {\n\t\t\ttoAdd = append(toAdd, pattern)\n\t\t}\n\t}\n\tif len(toAdd) == 0 {\n\t\treturn nil\n\t}\n","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/fs/beads.go#L130-L166","documentation":"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.","triggerScenarios":"Calling WriteProjectGitignore on a repository constructed without the project-gitignore pattern list (zero-length ProjectGitignorePatterns).","commonSituations":"Manual/zero-value struct construction in tests; a custom template source that returns an empty pattern slice; build/embed misconfiguration dropping the default patterns.","solutions":["Use the standard repository constructor so default ProjectGitignorePatterns are loaded","If supplying custom patterns, pass a non-empty slice of pattern strings","Check that embedded template assets are present in the build","Upgrade/repair local modifications that cleared the template configuration"],"exampleFix":"// before\ntpl := Templates{} // ProjectGitignorePatterns empty\nr := fsrepo.New(fsrepo.WithTemplates(tpl))\nr.WriteProjectGitignore(ctx) // patterns not configured\n// after\ntpl := fsrepo.DefaultTemplates() // includes ProjectGitignorePatterns\nr := fsrepo.New(fsrepo.WithTemplates(tpl))\nr.WriteProjectGitignore(ctx)","handlingStrategy":"validation","validationCode":"if len(projectGitignorePatterns) == 0 {\n\treturn errors.New(\"no ProjectGitignorePatterns provided; use fsrepo.DefaultTemplates()\")\n}\nrepo.WriteProjectGitignore(ctx)","typeGuard":"func hasProjectPatterns(t Templates) bool { return len(t.ProjectGitignorePatterns) > 0 }","tryCatchPattern":"if err := repo.WriteProjectGitignore(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"patterns not configured\") {\n\t\treturn fmt.Errorf(\"template set empty; rebuild repo with default templates\")\n\t}\n\treturn err\n}","preventionTips":["Source pattern lists from the bundled defaults, not hand-built structs","Assert non-empty templates in constructor/unit tests","Keep custom template providers returning the required pattern set","Re-check templates after major refactors of the embed assets"],"tags":["configuration","templates","initialization"],"backgroundTag":"missing-template-config","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}