{"record":{"id":"80ed9291483c356f","repo":"knadh/listmonk","slug":"template-d-not-found","errorCode":null,"errorMessage":"template %d not found","messagePattern":"template (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/manager/manager.go","lineNumber":363,"sourceCode":"\tm.tpls[id] = tpl\n\tm.tplsMut.Unlock()\n}\n\n// DeleteTpl deletes a cached template.\nfunc (m *Manager) DeleteTpl(id int) {\n\tm.tplsMut.Lock()\n\tdelete(m.tpls, id)\n\tm.tplsMut.Unlock()\n}\n\n// GetTpl returns a cached template.\nfunc (m *Manager) GetTpl(id int) (*models.Template, error) {\n\tm.tplsMut.RLock()\n\ttpl, ok := m.tpls[id]\n\tm.tplsMut.RUnlock()\n\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"template %d not found\", id)\n\t}\n\n\treturn tpl, nil\n}\n\n// TemplateFuncs returns the template functions to be applied into\n// compiled campaign templates.\nfunc (m *Manager) TemplateFuncs(c *models.Campaign) template.FuncMap {\n\tf := template.FuncMap{\n\t\t\"TrackLink\": func(url string, msg *CampaignMessage) string {\n\t\t\tif m.cfg.DisableTracking {\n\t\t\t\treturn url\n\t\t\t}\n\n\t\t\tsubUUID := msg.Subscriber.UUID\n\t\t\tif !m.cfg.IndividualTracking {\n\t\t\t\tsubUUID = dummyUUID\n\t\t\t}","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/internal/manager/manager.go#L345-L381","documentation":"GetTpl looks up a compiled template by numeric ID from the manager's in-memory template cache under a read lock. If no template with that ID is cached, this error is returned. It means the template either never existed, was deleted, or hasn't been loaded into the manager's cache yet.","triggerScenarios":"Requesting a campaign/template render with a template ID that was deleted (campaign still referencing it), an ID from another installation/database, or calling GetTpl before the manager finished loading templates from the store.","commonSituations":"Stale campaign rows pointing at removed templates, race at startup where a campaign scan runs before template cache warm-up completes, hardcoded template IDs in scripts/tests after DB resets, or importing data without templates.","solutions":["Verify the template ID exists (query the templates table / admin UI) and correct the reference","Re-load or refresh the manager's template cache (re-init or reload) so deleted/renamed templates are reflected","Repoint the campaign or code to an existing template ID","Ensure initialization order: load templates before starting the campaign scanner that may call GetTpl"],"exampleFix":"// before\ntpl, err := m.GetTpl(42) // stale id from deleted template\n// after\nid, err := resolveTemplateIDByName(\"welcome-email\")\nif err != nil { return err }\ntpl, err := m.GetTpl(id)","handlingStrategy":"try-catch","validationCode":"// Confirm the template exists before rendering a campaign\nif !templateExistsInStore(templateID) {\n    return fmt.Errorf(\"template %d does not exist; repoint campaign to a valid template\", templateID)\n}","typeGuard":null,"tryCatchPattern":"tpl, err := mgr.GetTpl(id)\nif err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        tpl, err = loadFallbackTemplate(mgr)\n    }\n    if err != nil { return err }\n}","preventionTips":["Never delete templates still referenced by campaigns; check references first","Warm the template cache before starting the campaign scanner","Store template references by resolvable name where possible and resolve at send time","After DB restores/imports, verify template IDs match campaigns"],"tags":["template","cache-miss","not-found","manager"],"backgroundTag":"resource-not-found","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}