kix.keep
kix.keep containerMarks a container “never collapse to absent”. Use it in constructors that
build a presence-meaningful field (an emptyDir volume source, a label
selector) from optional arguments that may all be null.
Argument and result
Section titled “Argument and result”| Input | Result |
|---|---|
| Attrset | The same attrset plus an additive _kixKeep marker. Resolved at mkResource; the marker never reaches rawManifest, the identity JSON, or the rendered output. |
| List | Normalized eagerly: null elements dropped; [ ] returned if nothing survives. No marker, because Nix merges replace lists wholesale, so a kept list cannot be re-filled with nulls later. |
| Anything else | Throws. |
Normalization background
Section titled “Normalization background”Rendering applies the collapse rule, bottom-up:
nullvalues are dropped.- A container that had members and lost all of them collapses to null and is omitted; the collapse cascades upward through wrappers.
- A container written literally empty (
{ },[ ]) renders as{}/[]. - Null list elements are dropped; an element that collapses entirely leaves its list.
kix.keep overrides the second point for one container: it renders {}
even when every member was null.
Behavior under merges
Section titled “Behavior under merges”| Operation | Result |
|---|---|
lib.recursiveUpdate kept { field = value; } | Field merges in; keep is preserved. |
lib.recursiveUpdate kept { field = null; } | Keep is preserved; the container still renders {} if everything collapses. |
attrs // { key = replacement; } | Wholesale replacement discards the keep, matching the author’s intent: the value was replaced. |
kix.keep (kix.keep x) | Same as applying it once. |
When it is not needed
Section titled “When it is not needed”- An explicit empty value (
emptyDir = { };) renders as-is. No keep required. - A constructor that filters its own nulls (
lib.optionalAttrs) produces a literal empty and needs no keep.kix.mount.emptyDirworks this way. - CRD schema subtrees rarely need it: the collapse rule keeps their literal
empties (
properties = { };) as written.
Related
Section titled “Related”- Keep intentionally empty values for the task-oriented guide.
- Built-in reliability rules:
the
volumeHasSourcerule fails the build on volumes that would render without a source.