{"record":{"id":"8f84c0c82a09e86e","repo":"knadh/listmonk","slug":"error-inserting-child-template-v","errorCode":null,"errorMessage":"error inserting child template: %v","messagePattern":"error inserting child template: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"models/campaigns.go","lineNumber":196,"sourceCode":"\t\t}\n\t\tbody = b.String()\n\t} else {\n\t\tbody = c.Body\n\t}\n\n\t// Compile the campaign message.\n\tfor _, r := range regTplFuncs {\n\t\tbody = r.regExp.ReplaceAllString(body, r.replace)\n\t}\n\n\tmsgTpl, err := template.New(ContentTpl).Funcs(f).Parse(body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error compiling message: %v\", err)\n\t}\n\n\tout, err := baseTPL.AddParseTree(ContentTpl, msgTpl.Tree)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error inserting child template: %v\", err)\n\t}\n\tc.Tpl = out\n\n\tif hasTplExpr(c.AltBody.String) {\n\t\tb := c.AltBody.String\n\t\tfor _, r := range regTplFuncs {\n\t\t\tb = r.regExp.ReplaceAllString(b, r.replace)\n\t\t}\n\t\tbTpl, err := template.New(ContentTpl).Funcs(f).Parse(b)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error compiling alt plaintext message: %v\", err)\n\t\t}\n\t\tc.AltBodyTpl = bTpl\n\t}\n\n\t// Compile any header values that contain template expressions.\n\tfor _, set := range c.Headers {\n\t\tfor _, val := range set {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/models/campaigns.go#L178-L214","documentation":"After parsing the body template, CompileTemplate attaches its parse tree into the base template via AddParseTree(ContentTpl, ...). This fails if the trees are incompatible (e.g. a template of the internal ContentTpl name already defined in baseTPL, or a conflicting tree).","triggerScenarios":"baseTPL.AddParseTree(ContentTpl, msgTpl.Tree) returns an error — typically because the body contains {{ define \"...\" }} blocks that collide with the internal ContentTpl name, or the msgTpl tree is inconsistent.","commonSituations":"Body contains {{ define \"...\" }} blocks that collide with the internal ContentTpl name; unusual custom bodies mixing define/inheritance; rarely hit by ordinary campaign bodies.","solutions":["Remove or rename any {{ define \"...\" }} blocks in the campaign body that could collide with the internal ContentTpl name","Keep the body as a single plain template without define blocks","Check the Go version's AddParseTree semantics if behavior changed after an upgrade"],"exampleFix":"// before\nbody = \"{{ define \\\"content\\\" }}Hi{{ end }}\"\n// after\nbody = \"Hi\"","handlingStrategy":"validation","validationCode":"if strings.Contains(body, \"{{ define\") {\n    return errors.New(\"body must not contain {{ define }} blocks\")\n}","typeGuard":null,"tryCatchPattern":"if err := c.CompileTemplate(); err != nil {\n    if strings.Contains(err.Error(), \"error inserting child template\") {\n        // strip define blocks from the body and recompile\n    }\n}","preventionTips":["Never use {{ define }} in campaign bodies","Treat the body as a single flat template","Add a compile smoke test that compiles every saved campaign after edits"],"tags":["template","go","campaign"],"backgroundTag":"template-parse-tree-conflict","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}