{"record":{"id":"abfcd6e1ae15d9bb","repo":"knadh/listmonk","slug":"error-compiling-header-q-v","errorCode":null,"errorMessage":"error compiling header %q: %v","messagePattern":"error compiling header %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"models/campaigns.go","lineNumber":234,"sourceCode":"\t\t\t\tc.HeaderTpls = make([]map[string]*txttpl.Template, len(c.Headers))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif c.HeaderTpls != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif c.HeaderTpls != nil {\n\t\tvar txtFuncs map[string]any = f\n\t\tfor i, set := range c.Headers {\n\t\t\tc.HeaderTpls[i] = make(map[string]*txttpl.Template, len(set))\n\t\t\tfor hdr, val := range set {\n\t\t\t\tif !hasTplExpr(val) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttpl, err := txttpl.New(ContentTpl).Funcs(txtFuncs).Parse(val)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error compiling header %q: %v\", hdr, err)\n\t\t\t\t}\n\t\t\t\tc.HeaderTpls[i][hdr] = tpl\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// hasTplExpr checks whether a given string has a Go template expression with {{ and  }}.\nfunc hasTplExpr(s string) bool {\n\t_, after, ok := strings.Cut(s, \"{{\")\n\treturn ok && strings.Contains(after, \"}}\")\n}\n\n// ConvertContent converts a campaign's body from one format to another,\n// for example, Markdown to HTML.\nfunc (c *Campaign) ConvertContent(from, to string) (string, error) {","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/models/campaigns.go#L216-L252","documentation":"Compilation of a custom campaign header value template failed while preparing the campaign for sending.","triggerScenarios":"CompileTemplate iterates c.Headers and a header value containing {{ ... }} has invalid syntax or calls an unknown function, e.g. header \"X-Campaign\": \"{{ badFunc .Name }}\".","commonSituations":"Custom mail headers (X-*) templated with subscriber data but containing typos; braces in header values intended as literals; header values copy-pasted with invalid actions.","solutions":["Fix the template syntax in the header named in the error","Remove template expressions from headers that don't need them (non-templated values are skipped)","Escape literal braces in header values","Test with previewTemplate which compiles headers the same way"],"exampleFix":"// before\n\"X-Custom\": \"{{ .Name \"\n// after\n\"X-Custom\": \"{{ .Name }}\"","handlingStrategy":"validation","validationCode":"for _, set := range headers {\n    for hdr, val := range set {\n        if strings.Contains(val, \"{{\") {\n            if _, err := txttpl.New(hdr).Parse(val); err != nil {\n                return fmt.Errorf(\"invalid template in header %s: %v\", hdr, err)\n            }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := c.CompileTemplate(); err != nil {\n    if strings.Contains(err.Error(), \"error compiling header\") {\n        // parse the header name from the message and fix that header's value\n    }\n}","preventionTips":["Only template headers that need subscriber data","Keep header values ASCII and simple; escape braces","Validate headers at campaign-save time"],"tags":["template","headers","campaign"],"backgroundTag":"template-parse-error","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}