{"record":{"id":"92d088dcb244c633","repo":"gohugoio/hugo","slug":"html-template-cannot-clone-q-after-it-has-execut-92d088","errorCode":null,"errorMessage":"html/template: cannot Clone %q after it has executed","messagePattern":"html/template: cannot Clone %q after it has executed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/htmltemplate/template.go","lineNumber":251,"sourceCode":"\t\tt.nameSpace,\n\t}\n\tt.set[name] = ret\n\treturn ret, nil\n}\n\n// Clone returns a duplicate of the template, including all associated\n// templates. The actual representation is not copied, but the name space of\n// associated templates is, so further calls to [Template.Parse] in the copy will add\n// templates to the copy but not to the original. [Template.Clone] can be used to prepare\n// common templates and use them with variant definitions for other templates\n// by adding the variants after the clone is made.\n//\n// It returns an error if t has already been executed.\nfunc (t *Template) Clone() (*Template, error) {\n\tt.nameSpace.mu.Lock()\n\tdefer t.nameSpace.mu.Unlock()\n\tif t.escapeErr != nil {\n\t\treturn nil, fmt.Errorf(\"html/template: cannot Clone %q after it has executed\", t.Name())\n\t}\n\ttextClone, err := t.text.Clone()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tns := &nameSpace{set: make(map[string]*Template)}\n\tns.esc = makeEscaper(ns)\n\tret := &Template{\n\t\tnil,\n\t\ttextClone,\n\t\ttextClone.Tree,\n\t\tns,\n\t}\n\tret.set[ret.Name()] = ret\n\tfor _, x := range textClone.Templates() {\n\t\tname := x.Name()\n\t\tsrc := t.set[name]\n\t\tif src == nil || src.escapeErr != nil {","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/htmltemplate/template.go#L233-L269","documentation":"Returned by html/template Clone (the full clone) at its initial guard: if t.escapeErr is non-nil (template was already escaped/executed), Clone refuses. Cloning an escaped template would duplicate frozen escaping state into a fresh nameSpace that expects unescaped input, so it is disallowed. The %q is t.Name().","triggerScenarios":"Calling (*htmltemplate.Template).Clone() on a Template whose escapeErr is set by a prior Execute/ExecuteTemplate/Prepare on it (escapeErr != nil and != escapeOK).","commonSituations":"Building per-request template variants by cloning after a warm-up render; reusing a base template that was already executed in a previous request; server code that executes then clones the same shared instance.","solutions":["Clone before the first Execute on the template or any associated template.","Keep an unexecuted master template and always clone from it; execute only the clones.","Rebuild with New + Parse instead of cloning when the template is already executed.","Reorder init code so cloning precedes any rendering."],"exampleFix":"// before\nt.Execute(w, data)\nclone, err := t.Clone() // error\n\n// after\nclone, err := t.Clone() // clone first\nif err != nil { return err }\nt.Execute(w, data)","handlingStrategy":"validation","validationCode":"// Maintain a master (unexecuted) template for cloning.\nvar masterT *template.Template\nfunc variant() (*template.Template, error) {\n    if masterT == nil {\n        return nil, fmt.Errorf(\"master not initialized\")\n    }\n    return masterT.Clone() // always clone the unexecuted master\n}","typeGuard":null,"tryCatchPattern":"clone, err := t.Clone()\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot Clone\") {\n        // rebuild a fresh master instead of cloning an executed one\n        master := template.New(t.Name())\n        if _, perr := master.Parse(masterBody); perr != nil { return nil, perr }\n        return master.Clone()\n    }\n    return nil, err\n}","preventionTips":["Keep an unexecuted master; execute only clones.","Clone once at setup before any render.","Treat execution as a one-way transition for a given set."],"tags":["go","html-template","clone","escaping"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}