{"record":{"id":"cffe7b2181c51740","repo":"helm/helm","slug":"s-labels-could-not-be-updated-w","errorCode":null,"errorMessage":"%s labels could not be updated: %w","messagePattern":"(.+?) labels could not be updated: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/action/validate.go","lineNumber":227,"sourceCode":"// setMetadataVisitor adds release tracking metadata to all resources. If forceOwnership is enabled, existing\n// ownership metadata will be overwritten. Otherwise an error will be returned if any resource has an\n// existing and conflicting value for the managed by label or Helm release/namespace annotations.\nfunc setMetadataVisitor(releaseName, releaseNamespace string, forceOwnership bool) resource.VisitorFunc {\n\treturn func(info *resource.Info, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif !forceOwnership {\n\t\t\tif err := checkOwnership(info.Object, releaseName, releaseNamespace); err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s cannot be owned: %w\", resourceString(info), err)\n\t\t\t}\n\t\t}\n\n\t\tif err := mergeLabels(info.Object, map[string]string{\n\t\t\tappManagedByLabel: appManagedByHelm,\n\t\t}); err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"%s labels could not be updated: %w\",\n\t\t\t\tresourceString(info), err,\n\t\t\t)\n\t\t}\n\n\t\tif err := mergeAnnotations(info.Object, map[string]string{\n\t\t\thelmReleaseNameAnnotation:      releaseName,\n\t\t\thelmReleaseNamespaceAnnotation: releaseNamespace,\n\t\t}); err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"%s annotations could not be updated: %w\",\n\t\t\t\tresourceString(info), err,\n\t\t\t)\n\t\t}\n\n\t\treturn nil\n\t}\n}","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/pkg/action/validate.go#L209-L245","documentation":"Thrown by setMetadataVisitor when mergeLabels fails: the generic metadata accessor (k8s.io/apimachinery meta.Accessor) could not read or write labels on the rendered object. This happens when the object passed to the visitor is a runtime.Object that does not expose ObjectMeta labels — most commonly aggregate/list kinds (e.g. kind: List, v1 SecretList) or malformed custom objects. Helm must stamp app.kubernetes.io/managed-by=Helm on every resource, so an object without a usable label set aborts the operation.","triggerScenarios":"A chart template renders a kind: List (or other list-type aggregate) as a top-level resource; a CRD-based object whose Go/unstructured representation lacks metadata.labels support; a template producing an object with empty/missing apiVersion or kind that confuses mapping; SDK users feeding non-standard runtime.Objects into the resource list.","commonSituations":"Templates copied from kubectl output that embed List wrappers; charts written for other templating engines; objects with TypeMeta stripped by faulty post-renderers (e.g. Kustomize misconfiguration); hand-built manifests with indentation errors making metadata unreachable.","solutions":["Fix the template to emit individual resources instead of a List wrapper — split list items into separate documents","Verify every rendered manifest has valid apiVersion, kind and metadata blocks: helm template ./chart | kubectl apply --dry-run=client -f - to validate","If using a post-renderer (Kustomize etc.), ensure it preserves metadata and does not emit list kinds","For SDK users: confirm the objects added to the ResourceList are standard or unstructured metadata-bearing objects"],"exampleFix":"# before: templates/stuff.yaml\napiVersion: v1\nkind: List\nitems:\n  - apiVersion: v1\n    kind: ConfigMap\n    metadata:\n      name: cm-one\n\n# after: templates/stuff.yaml\ndocuments emitted individually\n---\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: cm-one","handlingStrategy":"type-guard","validationCode":"// Before invoking the action, ensure every rendered manifest carries settable metadata:\nfunc metadataSafe(obj runtime.Object) bool {\n    _, err := meta.Accessor(obj)\n    return err == nil\n}\n// reject or rewrite objects failing metadataSafe() before building the ResourceList","typeGuard":"func isListKind(u *unstructured.Unstructured) bool {\n    return strings.HasSuffix(u.GetKind(), \"List\")\n}","tryCatchPattern":"if err := installAction.RunWithContext(ctx); err != nil {\n    if strings.Contains(err.Error(), \"labels could not be updated\") {\n        // inspect rendered manifests for List kinds / missing metadata and fix templates\n    }\n}","preventionTips":["Never emit kind: List from chart templates","Pipe helm template output through kubectl dry-run in CI to catch malformed objects","Test post-renderers (Kustomize) against charts that use labels/annotations","Keep templates one-object-per-file so metadata blocks stay attached"],"tags":["kubernetes","templates","labels","install","helm-action"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}