Skip to content

fix(secret): read pinnable secrets with dig to survive --reuse-values - #11

Merged
MartinHell merged 1 commit into
mainfrom
fix/nil-safe-session-encryption-values
Aug 21, 2026
Merged

fix(secret): read pinnable secrets with dig to survive --reuse-values#11
MartinHell merged 1 commit into
mainfrom
fix/nil-safe-session-encryption-values

Conversation

@MartinHell

Copy link
Copy Markdown
Contributor

Fixes #10.

The bug

helm upgrade --reuse-values from any chart ≤ 0.3.5 to 0.3.6 aborts at render:

Error: UPGRADE FAILED: template: patchmon/templates/secret.yaml:45:75:
executing "patchmon/templates/secret.yaml" at <.Values.patchmon.session.secret>:
nil pointer evaluating interface {}.secret

--reuse-values substitutes the previous release's values for the incoming chart's
defaults rather than merging them, so 0.3.6's new patchmon.session.secret and
patchmon.encryption.aiKey defaults are never coalesced in. A release created before
those keys existed has no patchmon.session / patchmon.encryption map at all, and
dereferencing the absent parent aborts the render.

patchmon.jwt.secret on the line above was unaffected only because patchmon.jwt
predates the keys added in #7, so every stored release already carries it.

This is the ordinary upgrade path for anyone whose values live outside git, and every
existing user is on ≤ 0.3.5 by definition.

The fix

Read all three through dig, which makes the parent lookup total — an absent map
yields the "" default and falls through to the existing lookup on the live Secret:

{{- $jwtVal     := dig "jwt"        "secret" "" .Values.patchmon -}}
{{- $sessionVal := dig "session"    "secret" "" .Values.patchmon -}}
{{- $aiKeyVal   := dig "encryption" "aiKey"  "" .Values.patchmon -}}

jwt is included for uniformity — it is equivalent today, and it stops the same class
of bug reappearing if that map is ever absent.

Chart bumped 0.3.6 → 0.3.7.

Verification

Reproduced deterministically with --set patchmon.session=null --set patchmon.encryption=null,
which forces the same nil parent:

published 0.3.6 this branch
render with nil session/encryption nil pointer evaluating interface {}.secret ✅ renders

Semantics unchanged:

  • explicit values still win — --set patchmon.jwt.secret=MYJWT etc. render MYJWT, MYSESSION, MYAIKEY
  • empty values still generate — 64-char randAlphaNum
  • the lookup fallback is untouched, so existing releases keep their current secrets

helm lint clean, both with defaults and with this deployment's shape
(database.mode=external, guacd.enabled=false). Chart.lock untouched, so the
"Ensure Chart.lock wasn't modified by CI" check passes.

Out of scope, but noted

--set patchmon.jwt=null still fails — in configmap-server.yaml:16 on
.Values.patchmon.jwt.expiresIn, not in secret.yaml. That is the same pattern
elsewhere in the chart, but it is not reachable through --reuse-values because
patchmon.jwt has always existed. Worth an audit pass separately; any value added to
an existing map in a future chart version has this problem.

Also worth considering: CI installs the chart fresh, which passes, so it could not have
caught an upgrade-path regression. A test that installs an older chart and upgrades with
--reuse-values would.

`helm upgrade --reuse-values` from any chart <= 0.3.5 to 0.3.6 failed to
render:

  secret.yaml:45:75: executing "patchmon/templates/secret.yaml" at
  <.Values.patchmon.session.secret>: nil pointer evaluating interface {}.secret

--reuse-values substitutes the previous release's values for the incoming
chart's defaults instead of merging them, so 0.3.6's new
patchmon.session.secret and patchmon.encryption.aiKey defaults are never
coalesced in. A release created before those keys existed has no
patchmon.session or patchmon.encryption map at all, and dereferencing the
absent parent aborts the render.

patchmon.jwt.secret was unaffected only because patchmon.jwt predates the
keys added in #7, so every stored release already carries it.

Reading all three through `dig` makes the parent lookup total: an absent map
yields the "" default and falls through to the existing lookup on the live
Secret, preserving the current values exactly as before. Explicitly set
values still win, and empty values still generate.

The failure is only reachable via --reuse-values; a fresh install or `-f
values.yaml` coalesces chart defaults normally, which is why CI did not catch
it. An upgrade-path test would.

Refs: #10

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8fLdB23wUNywajvRtNYbt
@MartinHell
MartinHell merged commit 2c6f87c into main Aug 21, 2026
1 check passed
@MartinHell
MartinHell deleted the fix/nil-safe-session-encryption-values branch August 21, 2026 23:55
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.

helm upgrade --reuse-values to 0.3.6 fails: nil pointer on patchmon.session.secret

1 participant