Skip to content

Lint Rules

The Helm lexicon ships lint rules that run during chant lint and post-synth checks that validate the generated chart after chant build.

Severity: error | Category: correctness

Flags Chart constructors missing required fields: name, version, or appVersion. Charts without these fields produce invalid Chart.yaml files.

Severity: error | Category: security

Flags Values constructors containing keys that match secret patterns (password, secret, token, apiKey, privateKey). Secrets should use Kubernetes Secrets or external secret managers, not values.yaml.

Severity: warning | Category: maintainability

Flags Deployment and container constructors with hardcoded image strings instead of values.* proxy references. Images should be parameterized through values.yaml for override flexibility.

WHM004 — HelmTpl expression in a Values constructor

Section titled “WHM004 — HelmTpl expression in a Values constructor”

Severity: warning | Category: correctness

Flags a HelmTpl expression inside a Values constructor, where it has no effect: values.yaml is plain data, so a Go template expression written there is emitted literally rather than evaluated. Use runtimeSlot() for a value that must resolve at deploy time.

WHM005 — Sub-chart wrapper with no templates

Section titled “WHM005 — Sub-chart wrapper with no templates”

Severity: warning

Flags a chart that declares sub-chart dependencies but ships no templates of its own. A wrapper that adds nothing should be dropped in favour of deploying the upstream chart directly.

RuleDescription
WHM101Chart.yaml must have required fields (apiVersion v2, name, version)
WHM102values.schema.json should be present when Values are non-empty
WHM103Go template syntax must be valid (balanced braces)
WHM104NOTES.txt should exist for application charts
WHM105_helpers.tpl must exist in templates/
RuleDescription
WHM201K8s resources should include standard Helm labels
WHM202Hook weights should be defined when multiple hooks exist
WHM203Values entries should be documented via schema or comments
WHM204Chart dependencies should use semver ranges, not pinned versions
RuleDescription
WHM301Application charts should include at least one Helm test
WHM302Container resources (limits/requests) should be set via values or defaults
RuleDescription
WHM401Container images should not use :latest tag or omit tag entirely
WHM402Containers should set runAsNonRoot in security context
WHM403Containers should set readOnlyRootFilesystem in security context
WHM404Containers must not run in privileged mode
WHM405Resource specs should include cpu and memory in limits/requests
WHM406CRDs in crds/ directory are never upgraded or deleted by Helm
WHM407Secrets with inline data should use ExternalSecret or SealedSecret
RuleDescription
WHM501Detect values keys that are defined but never referenced in templates
WHM502Detect deprecated or invalid Kubernetes API versions
WHM504Detect supplied values that never survive coalescing (dead assignments)

Helm coalesces values from several layers — each (sub)chart’s own values.yaml, the parent chart’s overrides under the dependency’s alias-or-name key, supplied values files, --set flags — and only the result reaches the templates. The coalesced tree exists on no side of the usual tooling: helm template --debug does not print it, and helm get values --all needs an installed release.

The lexicon extracts it at build time with a probe (probeCoalescedValues): the chart is copied, every (sub)chart’s templates are replaced with a single chant-values-probe.yaml template that prints {{ toYaml .Values }}, the copy is rendered, and the probe documents are lifted out. Coalescing is helm’s own — parent-overrides-child, global propagation, alias scoping and import-values all behave exactly as a real render, because it is a real render. The copy is discarded afterwards; the probe document can never appear in a real render of the chart. A dependency disabled by a condition: renders no probe document and is reported separately, with the condition that disabled it.

Three products come out of the probe:

  • a coalesced-values digest — sha256: over the canonical JSON of the per-instance trees, following the same conventions as the render input digest. Two renders that coalesce the same values everywhere share it.
  • valueSources — every coalesced path attributed to the layer that won it: chart default, parent override, supplied file, or --set (subchart paths are scope-prefixed, e.g. web.replicas). “Why is this field this value” becomes a lookup rather than a grep.
  • dead assignments — supplied values that never survive coalescing, which WHM504 reports.

Severity: warning

Flags a supplied value that never survives coalescing:

  • shadowed — a later supplied layer assigns the same path, so the earlier assignment is unreachable (two maps merging is not a shadow);
  • disabled subchart — the path targets a dependency a condition: disabled, so no rendered chart ever reads it;
  • unknown subchart — a values map under a top-level key that names no dependency, no chart default and not global, on a chart that has dependencies: the classic silently-ignored typo of a subchart name.

Each finding names the path, the layer that supplied it, and what shadowed or disabled it. The check reports over the probe runs of the current build; when no probe ran, it reports nothing.