{"record":{"id":"9cc19f6756912c8f","repo":"gastownhall/beads","slug":"cannot-modify-template-s-templates-are-read-only","errorCode":null,"errorMessage":"cannot modify template %s: templates are read-only; use 'bd mol pour' to create a work item","messagePattern":"cannot modify template (.+?): templates are read-only; use 'bd mol pour' to create a work item","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/validation/issue.go","lineNumber":46,"sourceCode":"// Exists validates that an issue is not nil.\nfunc Exists() IssueValidator {\n\treturn func(id string, issue *types.Issue) error {\n\t\tif issue == nil {\n\t\t\treturn fmt.Errorf(\"issue %s not found\", id)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// NotTemplate validates that an issue is not a template.\n// Templates are read-only and cannot be modified.\nfunc NotTemplate() IssueValidator {\n\treturn func(id string, issue *types.Issue) error {\n\t\tif issue == nil {\n\t\t\treturn nil // Let Exists() handle nil check if needed\n\t\t}\n\t\tif issue.IsTemplate {\n\t\t\treturn fmt.Errorf(\"cannot modify template %s: templates are read-only; use 'bd mol pour' to create a work item\", id)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// NotPinned validates that an issue is not pinned, by either of the two ways\n// bd expresses a pin: the Pinned boolean column or the pinned status. Returns\n// an error if either trigger fires, unless force is true.\n//\n// Both triggers are load-bearing because consumers disagree on which one they\n// write and read (ga-z3vht). Gas Town pins by status — it enumerates pins with\n// List(ListOptions{Status: StatusPinned}) across 21 sites (hook_check.go,\n// prime_output.go, molecule_step.go, up.go) — while Gas City reads the boolean\n// (compute_awake_set.go). Checking only one strips the other consumer's\n// protection outright, so do not \"simplify\" either clause away.\nfunc NotPinned(force bool) IssueValidator {\n\treturn func(id string, issue *types.Issue) error {\n\t\tif issue == nil {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/validation/issue.go#L28-L64","documentation":"NotTemplate() blocks writes against template issues. Templates (IsTemplate=true) are read-only definitions used by 'bd mol pour'; they must never be modified directly as work items.","triggerScenarios":"Any update/close/assign operation on an issue whose IsTemplate field is true — e.g. running 'bd update mol-xyz ...' or 'bd close' on a molecule template row.","commonSituations":"Mistaking a template ID for a work item ID when scripting; trying to edit a molecule template instead of pouring it into a real work item; bulk-update loops that sweep up templates.","solutions":["Use 'bd mol pour <template>' to create a real work item from the template, then modify that","Re-check the ID — templates and work items can look similar; 'bd show <id>' reveals IsTemplate","Exclude templates from bulk scripts by filtering on IsTemplate","If a template itself is wrong, update it only through the intended template-authoring flow, not general issue commands"],"exampleFix":"// before\nbd update bd-tmpl-1 status=in_progress  // blocked\n// after\nbd mol pour bd-tmpl-1  # creates work item bd-99\nbd update bd-99 status=in_progress","handlingStrategy":"validation","validationCode":"if issue.IsTemplate {\n    return fmt.Errorf(\"%s is a template; use 'bd mol pour' instead of modifying it\", id)\n}","typeGuard":"func isTemplate(issue *types.Issue) bool { return issue != nil && issue.IsTemplate }","tryCatchPattern":"if err := updateIssue(id); err != nil {\n    if strings.Contains(err.Error(), \"templates are read-only\") {\n        return pourFromTemplate(id) // fall back to pour flow\n    }\n    return err\n}","preventionTips":["Filter templates (IsTemplate) out of bulk update loops","Distinguish template IDs from work-item IDs before scripting","Prefer 'bd mol pour' whenever the source is a molecule template"],"tags":["validation","template","molecules","read-only"],"backgroundTag":"read-only-resource-modification","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}