{"record":{"id":"c8b1f32546d67a18","repo":"GoogleContainerTools/skaffold","slug":"invalid-component-specified-in-custom-template-v","errorCode":null,"errorMessage":"invalid component specified in custom template: %v","messagePattern":"invalid component specified in custom template: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/tag/custom_template.go","lineNumber":76,"sourceCode":"\n\t// missingkey=error throws error when map is indexed with an undefined key\n\ttag, err := ExecuteCustomTemplate(t.Template.Option(\"missingkey=error\"), customMap)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn tag, nil\n}\n\n// EvaluateComponents creates a custom mapping of component names to their tagger string representation.\nfunc (t *customTemplateTagger) EvaluateComponents(ctx context.Context, image latest.Artifact) (map[string]string, error) {\n\ttaggers := map[string]Tagger{}\n\n\ttemplateFields := GetTemplateFields(t.Template)\n\tfor _, field := range templateFields {\n\t\tif v, ok := t.Components[field]; ok {\n\t\t\tif _, ok := v.(*customTemplateTagger); ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid component specified in custom template: %v\", v)\n\t\t\t}\n\t\t\ttaggers[field] = v\n\t\t\tcontinue\n\t\t}\n\t\tswitch field {\n\t\tcase \"GIT\":\n\t\t\tgitTagger, _ := NewGitCommit(\"\", \"\", false)\n\t\t\ttaggers[field] = gitTagger\n\t\tcase \"DATE\":\n\t\t\ttaggers[field] = NewDateTimeTagger(\"\", \"\")\n\t\tcase \"SHA\":\n\t\t\ttaggers[field] = &ChecksumTagger{}\n\t\tcase \"INPUT_DIGEST\":\n\t\t\tinputDigestTagger, _ := NewInputDigestTagger(t.RunCtx, graph.ToArtifactGraph(t.RunCtx.Artifacts()))\n\t\t\ttaggers[field] = inputDigestTagger\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"no tagger available for component %+v\", field)\n\t\t}","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/tag/custom_template.go#L58-L94","documentation":"A template field resolved to a customTemplateTagger, i.e. a custom template component referenced itself (directly or transitively), which would cause infinite recursion. `EvaluateComponents` rejects this with this error naming the offending component.","triggerScenarios":"`GenerateTag` calls `EvaluateComponents`; `GetTemplateFields` finds a field present in `t.Components`, but the value's concrete type is `*customTemplateTagger` — meaning a custom template component is nested inside another custom template's fields.","commonSituations":"Defining a custom tagger whose template includes a field mapped to another (or the same) custom template tagger in the components map; misconfigured `components` wiring that creates a cycle.","solutions":["Remove the nested custom-template component from the components map","Use a primitive tagger component (DATE, SHA, GIT, LABEL, DIGEST, INPUT_DIGEST) for that field instead","Refactor so the inner template's fields are expanded into the outer template directly"],"exampleFix":"// before: component map with recursion\ncomponents: {SUB: customTemplateTagger}\ncustomTemplate: \"{{.SUB}}-{{.SHA}}\"\n// after: reference primitives only\ncustomTemplate: \"{{.GIT}}-{{.SHA}}\"","handlingStrategy":"validation","validationCode":"// ensure no component maps to a custom template tagger (no recursion)\nfor name, comp := range components {\n    if _, bad := comp.(*tag.CustomTemplateTagger); bad {\n        return fmt.Errorf(\"component %q must not be a custom template tagger\", name)\n    }\n}","typeGuard":"func isPrimitiveTagger(t tag.Tagger) bool {\n    switch t.(type) {\n    case *tag.CustomTemplateTagger:\n        return false\n    default:\n        return true\n    }\n}","tryCatchPattern":null,"preventionTips":["Never nest custom templates in the components map","Compose templates from primitive components only (GIT, SHA, DATE...)","Sketch the component graph to spot cycles before configuring","Review skaffold.yaml tagger config in code review"],"tags":["templating","configuration","recursion"],"backgroundTag":"template-component-recursion","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}