Skip to content

Remove duplicate app.kubernetes.io/name label from rendered manifests#216

Merged
squat merged 3 commits into
squat:mainfrom
inistor:fix/duplicate-label-render
May 13, 2026
Merged

Remove duplicate app.kubernetes.io/name label from rendered manifests#216
squat merged 3 commits into
squat:mainfrom
inistor:fix/duplicate-label-render

Conversation

@inistor
Copy link
Copy Markdown
Contributor

@inistor inistor commented May 13, 2026

Summary

The DaemonSet and PodMonitor templates emit app.kubernetes.io/name: generic-device-plugin twice on the same labels map — once literally, once via {{- include "generic-device-plugin.labels" . | nindent N }} (which transitively includes selectorLabels, which emits the same key). Helm tolerates duplicate map keys (last-wins), but strict YAML parsers — Kustomize, Flux v2's Kustomize-based postRenderers, ArgoCD with strict parsing, kubeconform, etc. — reject the rendered output.

Reproduction (before this patch)

$ helm pull oci://ghcr.io/squat/charts/generic-device-plugin --version 0.1.1
$ helm template test ./generic-device-plugin-0.1.1.tgz > rendered.yaml
$ mkdir k && cp rendered.yaml k/ && printf 'resources:\n  - rendered.yaml\n' > k/kustomization.yaml
$ kustomize build k
Error: map[string]interface {}(nil): yaml: unmarshal errors:
  line 10: mapping key "app.kubernetes.io/name" already defined at line 8
  line 23: mapping key "app.kubernetes.io/name" already defined at line 21

Rendered excerpt that triggers the failure:

metadata:
  labels:
    app.kubernetes.io/name: generic-device-plugin     # ← literal in template
    helm.sh/chart: generic-device-plugin-0.1.1
    app.kubernetes.io/name: generic-device-plugin     # ← re-emitted by helper
    app.kubernetes.io/instance: test
    app.kubernetes.io/version: "0.2.0"
    app.kubernetes.io/managed-by: Helm

Fix

Drop the three literal app.kubernetes.io/name: generic-device-plugin lines. The generic-device-plugin.labels helper already emits the same value via selectorLabels, so all rendered labels are identical to before — just deduplicated.

matchLabels blocks (DaemonSet spec.selector.matchLabels, PodMonitor spec.selector.matchLabels) intentionally keep the literal — those have to match what selectorLabels emits.

Verification after this patch

$ helm template test ./inistor-generic-device-plugin/charts/generic-device-plugin > rendered.yaml
$ kustomize build k
# (clean output; PASS)

DaemonSet metadata.labels after patch:

labels:
  app.kubernetes.io/instance: test
  app.kubernetes.io/managed-by: Helm
  app.kubernetes.io/name: generic-device-plugin     # only once now
  app.kubernetes.io/version: "0.2.0"
  helm.sh/chart: generic-device-plugin-0.1.1

Context

Found this trying to install the chart via Flux v2 with a Kustomize postRenderers patch to extend the --device list with /dev/kvm (separately tracked in #209 / #206). The duplicate-label bug aborts the Helm install before any resource is applied, even with no postRenderer specified if any other tooling in the GitOps pipeline parses the rendered manifests strictly. We worked around it by shipping a raw DaemonSet manifest, but the chart is otherwise exactly what we want — so this small fix unblocks postRenderer-based usage.


Investigation and patch prepared with assistance from Claude (Anthropic's CLI for software engineering).

The label is already emitted by the `generic-device-plugin.labels`
helper via `selectorLabels`. Having it set both literally and
through the helper produces a duplicate map key in the rendered
YAML. Helm tolerates that (last-wins), but strict YAML parsers
(Kustomize, Flux v2 postRenderers, kubeconform, ArgoCD with
strict parsing) reject the output, blocking GitOps installs that
postRender the chart.

matchLabels selectors are unchanged — they intentionally rely on
the literal value matching what selectorLabels emits.
Copy link
Copy Markdown
Owner

@squat squat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you bump the chart's patch version too?

Patch bump for the duplicate-label rendering fix.
@inistor
Copy link
Copy Markdown
Contributor Author

inistor commented May 13, 2026

Done — bumped version to 0.1.2 in Chart.yaml (patch bump, since this is a bugfix). Pushed as 246cbff.

@squat squat enabled auto-merge May 13, 2026 14:04
@squat
Copy link
Copy Markdown
Owner

squat commented May 13, 2026

Thanks @inistor

@inistor
Copy link
Copy Markdown
Contributor Author

inistor commented May 13, 2026

Thanks @inistor

Thank you for the quick response

auto-merge was automatically disabled May 13, 2026 14:15

Head branch was pushed to by a user without write access

@squat squat enabled auto-merge May 13, 2026 14:24
@squat squat merged commit d660d1f into squat:main May 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants