Skip to content

fix(helm): preserve empty-list overrides in valueYamlFiles when allowNullValues=false#4269

Open
ctrahey wants to merge 3 commits intopulumi:masterfrom
ctrahey:trahey/bugfix-values-override-to-nil
Open

fix(helm): preserve empty-list overrides in valueYamlFiles when allowNullValues=false#4269
ctrahey wants to merge 3 commits intopulumi:masterfrom
ctrahey:trahey/bugfix-values-override-to-nil

Conversation

@ctrahey
Copy link
Copy Markdown

@ctrahey ctrahey commented Apr 5, 2026

Issue

Chart rendering is different through pulumi-kubernetes than helm when a values file overrides a list to be empty.

Proposed changes

excludeNulls recurses into slice values using var out []any. When the input slice is empty, the loop never runs, so out remains nil and is returned that way. That nil slice is written back into the filtered values map, and later Helm value coalescing distinguishes nil []any from a non-nil empty []any{}: the nil form does not preserve the user’s explicit empty-list override, so the chart default is applied instead. Changing this to out := make([]any, 0) ensures an empty input slice round-trips as a non-nil empty slice and survives the merge as an explicit override.

Notes on discovery and repro

I discovered this when I refactored a project from manual helm deployments to using this provider in Pulumi and started seeing issues in my workload, because the chart I was using had some default podSecurityContext.sysctls that I needed to remove in my environment. My local values file set the list to the empty list:

# in the upstream chart's values:
podSecurityContext:
  sysctls:
    - name: net.ipv4.tcp_keepalive_time
      value: "300"

# in my local values file
podSecurityContext:
  sysctls: []

This worked great via helm. But using the pulumi-kubernetes provider did not behave the same way and was shipping the chart-defaults to my cluster instead. I reproduced this with a minimal setup that deployed the same chart with same values overrides via helm and via pulumi and observe different resultant configuration in the live cluster (let me know if you want to see the minimal repro and I can push a quick public repo or gist).

Disclosure: I used a combination of Codex (where I was doing the main project work when I discovered this, had it do the initial reproduction and initial hypothesis) and Claude Code with Opus 4.6 (where I honed in on this specific issue and worked up the minimal tests and fix). However, I'm generally a skeptic of agentic coding, so I've been careful to read through everything here (small as it is lol) and while I'm not a go programmer, this seems succinct and reasonable to me. I'm happy to followup with any additional contribution steps.

ctrahey and others added 2 commits April 5, 2026 10:30
Two tests that currently fail, covering the same root bug at
different levels:

- Test_MergeMaps/empty_list_overrides_non-empty_list_with_allowNil=false
  exercises mergeMaps directly

- TestDecodeRelease/valueYamlFiles_with_empty_list_is_preserved
  exercises the full decodeRelease path with a valueYamlFiles asset

Root cause: excludeNulls returns a nil slice (not []any{}) for an
empty input slice, making [] indistinguishable from a missing key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`var out []any` is a nil slice. When the input slice is empty the loop
body never executes, so nil is returned and the caller cannot
distinguish "empty list" from "key not present". Helm then falls back
to the chart default instead of honouring `items: []` from a
valueYamlFiles override.

Change to `make([]any, 0)` so an empty input slice produces a non-nil
`[]any{}`, which survives the subsequent mergo merge as an explicit
empty-list override.

Fixes the `allowNullValues=false` (default) case where `items: []` in
a valueYamlFiles entry was silently dropped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

PR is now waiting for a maintainer to run the acceptance tests.
Note for the maintainer: To run the acceptance tests, please comment /run-acceptance-tests on the PR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026

PR is now waiting for a maintainer to run the acceptance tests.
Note for the maintainer: To run the acceptance tests, please comment /run-acceptance-tests on the PR

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.

1 participant