Warnings and safe fallbacks
OINK does not call Hugo’s errorf. Invalid author or site input emits a
warning and either uses a documented safe fallback or omits the invalid
fragment. Release and deployment builds use --panicOnWarning, so the same
warning remains a hard publishing failure.
Context
Hugo builds the whole site as one transaction. An errorf raised while one
page is being edited makes every URL served by that rebuild return an error,
including unrelated pages and the home page. The server process survives and
recovers after the input is fixed, but collaborative preview is unavailable in
the meantime.
A warning has a different development cost. The affected value can fall back,
the rest of the site remains inspectable, and the author receives a precise
message. A publication build still fails because OINK’s CI and integration
gates add --panicOnWarning.
Decision
Validation follows four rules:
- Name the invalid key and value, the allowed shape, and the fallback.
- Include a page position when the value came from page front matter; avoid repeating one site-wide warning for every page.
- Never pass an invalid value into a later operation. Validate first, then render from the normalized value.
- Where no honest fallback exists, warn and render nothing. Do not invent content, make a network request, or emit an unsafe URL merely to keep going.
The shared enum, boolean, CSS-length, and number shapes live in
layouts/_partials/validate.html. Domain resolvers may add narrower checks,
but they preserve the same warning/fallback contract.
Safety boundary
Continuing a build never means continuing with unsafe output. A rejected CSS length falls back before it reaches a style attribute. An incomplete remote service configuration omits the component before the browser can make a request. An unsafe action URL is dropped. The protection is the absence of the bad output, not the act of terminating Hugo.
This also separates editing from publication cleanly:
| Stage | Invalid input |
|---|---|
hugo server or an ordinary local build |
Warn, fall back or omit, keep other pages available |
| CI, release validation, deployment | The same warning becomes a non-zero build under --panicOnWarning |
Consequences
- Every fallback is part of the public contract and must match the default declared by the theme.
- A change from failure to fallback also changes its tests. A negative test proves ordinary build survival, the warning text, the rendered fallback, and strict-build failure.
- Checkers must test the rejected output directly. A URL security test, for example, asserts that the unsafe URL is absent instead of treating any build failure as sufficient proof.
- The source-level parameter checker protects the invariant that theme layouts
contain no
errorfcalls.
Verification
The owning references are the
architecture contract,
bin/check-params.py, and strict builds of both the theme fixture and this
integration site.