{"record":{"id":"7d47fa3ea74edebd","repo":"kubernetes/kops","slug":"rendering-addon-q-for-image-discovery-w","errorCode":null,"errorMessage":"rendering addon %q for image discovery: %w","messagePattern":"rendering addon %q for image discovery: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go","lineNumber":302,"sourceCode":"}\n\n// CollectImages renders template sources under stubbed task funcs and scans\n// the resulting YAML for image references to pre-register with the builder.\n// Best-effort only (used for AWS WarmPool image prewarm): a failure here\n// warns rather than breaks the build.\nfunc (a *Addon) CollectImages(assetBuilder *assets.AssetBuilder, renderer AddonTemplateRenderer) error {\n\tif a == nil || assetBuilder == nil || a.Source == nil {\n\t\treturn nil\n\t}\n\n\tmanifestBytes, err := fi.ResourceAsBytes(a.Source)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !a.SkipRender && renderer != nil {\n\t\tmanifestBytes, err = renderer.RenderTemplate(addonKey(a.Spec), manifestBytes, nil)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"rendering addon %q for image discovery: %w\", addonKey(a.Spec), err)\n\t\t}\n\t}\n\t_, err = assetBuilder.RemapManifest(manifestBytes)\n\treturn err\n}\n\nfunc (b *BootstrapChannelBuilder) buildAddons(c *fi.CloudupModelBuilderContext) (*AddonList, map[types.NamespacedName]iam.Subject, error) {\n\taddons := &AddonList{}\n\n\tserviceAccountRoles := []iam.Subject{}\n\n\t{\n\t\tkey := \"kops-controller.addons.k8s.io\"\n\n\t\t{\n\t\t\tlocation := key + \"/k8s-1.16.yaml\"\n\t\t\tid := \"k8s-1.16\"\n","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/bootstrapchannelbuilder/bootstrapchannelbuilder.go#L284-L320","documentation":"CollectImages renders each addon manifest (unless SkipRender) with renderer.RenderTemplate in order to discover container images before remapping. If template rendering fails, the error is wrapped with the addon key so the failing addon can be identified.","triggerScenarios":"Calling CollectImages on a channel whose addon manifest is a template containing invalid Go-template constructs or functions the renderer cannot evaluate; addon has SkipRender=false and a non-nil renderer.","commonSituations":"Hand-edited addon templates with unbalanced {{ }}; templates referencing functions removed in a kops upgrade; custom addon channels built with the wrong template syntax.","solutions":["Check the wrapped error from RenderTemplate for the template syntax problem","Fix the Go-template syntax in the addon manifest at the named addon key","Set the addon as a raw source (SkipRender) if it needs no templating","Upgrade/downgrade kops so template functions match the channel"],"exampleFix":"// before (addon template)\nimage: {{ .Image }}\n// after: balanced, valid template\nimage: \"{{ .Image }}\"","handlingStrategy":"try-catch","validationCode":"// Pre-check template balance before CollectImages\nif bytes.Count(manifestBytes, []byte(\"{{\")) != bytes.Count(manifestBytes, []byte(\"}}\")) {\n    return fmt.Errorf(\"addon %s has unbalanced template delimiters\", addonKey(a.Spec))\n}","typeGuard":null,"tryCatchPattern":"if err := a.CollectImages(ctx, renderer, assetBuilder); err != nil {\n    if strings.Contains(err.Error(), \"rendering addon\") {\n        var rerr error\n        errors.As(err, &rerr) // wrapped RenderTemplate error\n        klog.Errorf(\"fix template for addon %s: %v\", addonKey(a.Spec), err)\n    }\n    return err\n}","preventionTips":["Lint Go templates in custom addon channels before publishing","Prefer raw (non-template) manifests when templating is unnecessary","Test rendering with text/template parse before channel release"],"tags":["addons","templating","images","kops"],"backgroundTag":"template-render-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}