Skip to content

v1.7.5 — undef is a default

Choose a tag to compare

@eth-man eth-man released this 17 Aug 16:59
· 34 commits to main since this release

A parameter defaulting to undef is optional, not required

Reported from a live console. A class declaring

Optional[String[1]] $cloud = undef,

was shown as required — along with three more like it, above a header announcing "6 required parameters" for a class that has two.

= undef is a default. It is precisely what makes such a parameter omissible. What makes one required is the absence of any =, which arrives as neither default_literal nor default_source.

The old reasoning, written in a comment, was half right:

undef is Puppet for "no default value", not a default of the string "undef".

The second clause is true. The first is not.

And a test asserted the mistake — "treats an undef default as required" — converting it into a guarantee the suite would have defended against anybody trying to fix it. A test that pins wrong behaviour is worse than no test. It is inverted now, and the reported class is held as a fixture: two required, four optional, enum default still read correctly.

The console drops the red required badge on these, says "optional — leave blank to omit", and stops counting them toward the required total.

Two conditions for a fault found in our own lab

Configuration pulled from one instance, telemetry pushed to another. A Puppet server fetched the tree 2705 times and reported nothing, while a second deployment banked receipts for a tree it never served. The estate converged perfectly the whole time; only the answer to "did it land" was broken, and the propagation front sat at compiled 0/N indefinitely with no way to tell that from "no agent has run yet".

  • replication.not-reporting — a peer that has held a tree for four run intervals and never reported. Names the two causes: a collector pointed at another origin, or one that is not running.
  • replication.unexpected-receipts — a peer reporting compiles without ever having fetched, which it therefore could not have run.

Both are warnings. Nothing is misconfigured on the estate and no node is wrong; what is lost is visibility, and calling that critical teaches people to ignore critical.

Neither compares revisions, which was the obvious design and does not work: the only stored record of a served revision is the peer's last etag, so a differing revision cannot be told apart from an agent legitimately running behind — and flagging every lagging agent as foreign would be worse than the bug.

Upgrading

No migrations. No schema change; the new conditions are derived from data already stored.