#9 fixed script/check so that script/lint actually runs. But the signal it
recovers is printed and then ignored, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
script/test (hugo --minify) — prints nothing, exit 0.
script/lint (hugo --minify --printPathWarnings) — prints WARN Duplicate target paths: /collide/index.html (2), and exits 0.
script/check with the collision present — exit 0.
So a real render-target collision does not fail make check, does not fail the
pre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: #9's rationale was mildly overstated, and I
wrote it. I described script/lint as "a real check" whose signal was "being
discarded". The accurate version is that the signal moves from discarded to printed-and-ignored. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in public/. One of them does not get published, and nothing fails. On a
site whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy WARN (#13). Two classes of ignorable warning train everyone to
ignore the third.
Options
Option A — --panicOnWarning on script/lint (recommended, but see the
caveat). Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. Caveat: it makes ALL warnings fatal,
not just collisions. That means #13 (the taxonomy layout warning) and #18
(the languageCode deprecation) must be fixed first, or the gate goes red
immediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
Option B — grep the lint output for the specific warning and fail on it.
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in script/lint that has to keep matching
Hugo's message text — brittle across Hugo upgrades in a way Option A is not.
Option C — leave it advisory and rely on humans reading build output. Not
recommended; that is the status quo and the reason this issue exists.
My recommendation: Option A, sequenced after #13 and #18. It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
Definition of done
A render-target collision causes make check to exit non-zero.
Demonstrated the way it was found: construct a collision on a scratch copy
(do not commit colliding content), show make check failing, remove it,
show make check passing. Paste both.
If Option A: #13 and #18 are closed first, and make check is confirmed
green on the real site with the flag active before the flag is merged.
script/lint's header comment describes the new behaviour accurately —
it currently claims it "is a real check", which this issue shows is only
half true today.
script/cibuild succeeds, with the check layer confirmed genuinely executed
and not CACHED (see #23).
TODO.md updated in the same commit.
Depends on
#13 (taxonomy warning) and #18 (languageCode deprecation) if Option A is
chosen. Both must be closed first or the gate fails on day one.
Interacts with #23: verifying this needs a genuinely-executed check layer.
Making script/test strict. script/test is the plain production build and
should stay the fast path; enforcement belongs in script/lint.
## Problem
#9 fixed `script/check` so that `script/lint` actually runs. But the signal it
recovers is **printed and then ignored**, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
- `script/test` (`hugo --minify`) — prints nothing, exit 0.
- `script/lint` (`hugo --minify --printPathWarnings`) — prints
`WARN Duplicate target paths: /collide/index.html (2)`, and **exits 0**.
- `script/check` with the collision present — **exit 0**.
So a real render-target collision does not fail `make check`, does not fail the
pre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: **#9's rationale was mildly overstated, and I
wrote it.** I described `script/lint` as "a real check" whose signal was "being
discarded". The accurate version is that the signal moves from *discarded* to
*printed-and-ignored*. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
## Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in `public/`. One of them does not get published, and nothing fails. On a
site whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy `WARN` (#13). Two classes of ignorable warning train everyone to
ignore the third.
## Options
**Option A — `--panicOnWarning` on `script/lint` (recommended, but see the
caveat).** Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. **Caveat: it makes ALL warnings fatal,
not just collisions.** That means #13 (the taxonomy layout warning) and #18
(the `languageCode` deprecation) must be fixed first, or the gate goes red
immediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
**Option B — grep the lint output for the specific warning and fail on it.**
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in `script/lint` that has to keep matching
Hugo's message text — brittle across Hugo upgrades in a way Option A is not.
**Option C — leave it advisory and rely on humans reading build output.** Not
recommended; that is the status quo and the reason this issue exists.
**My recommendation: Option A, sequenced after #13 and #18.** It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
## Definition of done
1. A render-target collision causes `make check` to exit non-zero.
2. Demonstrated the way it was found: construct a collision on a scratch copy
(do **not** commit colliding content), show `make check` failing, remove it,
show `make check` passing. Paste both.
3. If Option A: `#13` and `#18` are closed first, and `make check` is confirmed
green on the real site with the flag active before the flag is merged.
4. `script/lint`'s header comment describes the new behaviour accurately —
it currently claims it "is a real check", which this issue shows is only
half true today.
5. `script/cibuild` succeeds, with the check layer confirmed genuinely executed
and not `CACHED` (see #23).
6. `TODO.md` updated in the same commit.
## Depends on
- #13 (taxonomy warning) and #18 (`languageCode` deprecation) if Option A is
chosen. Both must be closed first or the gate fails on day one.
- Interacts with #23: verifying this needs a genuinely-executed check layer.
## Out of scope
- Fixing #13 or #18 themselves.
- Making `script/test` strict. `script/test` is the plain production build and
should stay the fast path; enforcement belongs in `script/lint`.
Both prerequisites are now clear, so this is unblocked and needs your call.
#18 (languageCode deprecation) — closed, merged in PR #27.
#13 (taxonomy warning) — fixed in PR #29, under review. Build output is
warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: Option A, --panicOnWarning on script/lint.
Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make: --panicOnWarning makes every Hugo warning fatal,
not just render-target collisions. The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on main, and including the deploy path. That is
arguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to script/lint once you pick.
Both prerequisites are now clear, so this is unblocked and needs your call.
- #18 (`languageCode` deprecation) — closed, merged in PR #27.
- #13 (taxonomy warning) — fixed in PR #29, under review. Build output is
warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: **Option A**,
`--panicOnWarning` on `script/lint`.
Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make: **`--panicOnWarning` makes every Hugo warning fatal,
not just render-target collisions.** The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on `main`, and including the deploy path. That is
arguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to `script/lint` once you pick.
Plan, building option (a) as approved: Hugo's own --panicOnWarning on the lint build. One branch off next, one PR to next.
Dockerfile.lint: the lint step becomes hugo --minify --printPathWarnings --panicOnWarning. --printPathWarnings stays, since it is what makes Hugo report two pages writing the same output file; --panicOnWarning turns that report, and any other Hugo warning, into a failed build. The header comment says so.
script/lint header comment: the lint fails on any Hugo warning, including two pages that write the same output path.
README.md: the script/lint bullet under Entrypoints says the same.
TODO.md: a short Completed Steps entry, and this item removed from Blocked.
script/test and the deploy workflow are unchanged: only the lint is strict.
Before opening the PR, on a scratch copy that is never committed: two pages that render to the same path (for example two files under content/ with the same url in their front matter) make script/lint exit non-zero, and with them removed script/lint and script/check pass on the real site. The PR body gives that recipe in two lines so the reviewer can repeat it. If the pinned Hugo does not stop on that warning under --panicOnWarning, the fallback is to fail the lint step when its output carries Hugo's duplicate target paths warning, stated on the PR.
Model: opus-5-5
Plan, building option (a) as approved: Hugo's own `--panicOnWarning` on the lint build. One branch off `next`, one PR to `next`.
1. `Dockerfile.lint`: the lint step becomes `hugo --minify --printPathWarnings --panicOnWarning`. `--printPathWarnings` stays, since it is what makes Hugo report two pages writing the same output file; `--panicOnWarning` turns that report, and any other Hugo warning, into a failed build. The header comment says so.
2. `script/lint` header comment: the lint fails on any Hugo warning, including two pages that write the same output path.
3. `README.md`: the `script/lint` bullet under Entrypoints says the same.
4. `TODO.md`: a short Completed Steps entry, and this item removed from Blocked.
5. `script/test` and the deploy workflow are unchanged: only the lint is strict.
Before opening the PR, on a scratch copy that is never committed: two pages that render to the same path (for example two files under `content/` with the same `url` in their front matter) make `script/lint` exit non-zero, and with them removed `script/lint` and `script/check` pass on the real site. The PR body gives that recipe in two lines so the reviewer can repeat it. If the pinned Hugo does not stop on that warning under `--panicOnWarning`, the fallback is to fail the lint step when its output carries Hugo's duplicate target paths warning, stated on the PR.
Model: opus-5-5
Built as planned in #46: the lint step runs with --panicOnWarning, and Hugo stops on its own duplicate target paths warning, so no fallback was needed. The PR has the steps to repeat the check. They include a one-line scratch page layout, because the theme has no layout for ordinary pages.
Model: opus-5-5
Built as planned in https://git.eeqj.de/sneak/lora.vegas/pulls/46: the lint step runs with `--panicOnWarning`, and Hugo stops on its own duplicate target paths warning, so no fallback was needed. The PR has the steps to repeat the check. They include a one-line scratch page layout, because the theme has no layout for ordinary pages.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
#9 fixed
script/checkso thatscript/lintactually runs. But the signal itrecovers is printed and then ignored, because Hugo exits 0 on a duplicate
render-target warning.
Demonstrated during the review of PR #24, on a scratch copy of the site with
two pages rendering to the same permalink:
script/test(hugo --minify) — prints nothing, exit 0.script/lint(hugo --minify --printPathWarnings) — printsWARN Duplicate target paths: /collide/index.html (2), and exits 0.script/checkwith the collision present — exit 0.So a real render-target collision does not fail
make check, does not fail thepre-commit hook, and does not fail CI. It scrolls past in the build log.
This is worth stating plainly: #9's rationale was mildly overstated, and I
wrote it. I described
script/lintas "a real check" whose signal was "beingdiscarded". The accurate version is that the signal moves from discarded to
printed-and-ignored. That is a genuine improvement — you cannot act on output
that never runs — but it is not yet a gate, and #9's issue text implied it was.
Correcting the record here rather than leaving the overstatement standing.
Why this matters for a Hugo site
A duplicate render target means two pieces of content silently overwrite each
other in
public/. One of them does not get published, and nothing fails. On asite whose entire purpose is publishing a small number of pages, losing one
silently is exactly the failure you want a gate to catch. It has not bitten
this repo yet only because the site is currently a single page.
There is also a build-noise interaction: the site already emits an unrelated
taxonomy
WARN(#13). Two classes of ignorable warning train everyone toignore the third.
Options
Option A —
--panicOnWarningonscript/lint(recommended, but see thecaveat). Hugo's documented mechanism for making warnings fatal. One flag,
correct semantics, no bespoke parsing. Caveat: it makes ALL warnings fatal,
not just collisions. That means #13 (the taxonomy layout warning) and #18
(the
languageCodedeprecation) must be fixed first, or the gate goes redimmediately. It also means a future Hugo release that adds a new warning
category can break the build — arguably correct behaviour, but it should be a
conscious choice.
Option B — grep the lint output for the specific warning and fail on it.
Narrower: fails only on duplicate target paths, leaves other warnings advisory.
Costs a bespoke shell pipeline in
script/lintthat has to keep matchingHugo's message text — brittle across Hugo upgrades in a way Option A is not.
Option C — leave it advisory and rely on humans reading build output. Not
recommended; that is the status quo and the reason this issue exists.
My recommendation: Option A, sequenced after #13 and #18. It is the
supported mechanism and it makes the whole warning class meaningful rather than
carving out one message. The dependency on #13 and #18 is a feature — it forces
the existing warning backlog to zero before warnings become enforcing, which is
the only order in which "warnings are fatal" is a livable policy.
Definition of done
make checkto exit non-zero.(do not commit colliding content), show
make checkfailing, remove it,show
make checkpassing. Paste both.#13and#18are closed first, andmake checkis confirmedgreen on the real site with the flag active before the flag is merged.
script/lint's header comment describes the new behaviour accurately —it currently claims it "is a real check", which this issue shows is only
half true today.
script/cibuildsucceeds, with the check layer confirmed genuinely executedand not
CACHED(see #23).TODO.mdupdated in the same commit.Depends on
languageCodedeprecation) if Option A ischosen. Both must be closed first or the gate fails on day one.
Out of scope
script/teststrict.script/testis the plain production build andshould stay the fast path; enforcement belongs in
script/lint.Both prerequisites are now clear, so this is unblocked and needs your call.
languageCodedeprecation) — closed, merged in PR #27.warning-free.
So the noise floor is genuinely zero and Option A would no longer fail the
build on day one. My recommendation is unchanged: Option A,
--panicOnWarningonscript/lint.Assigning to you because the caveat in the issue body is the whole decision and
it is not mine to make:
--panicOnWarningmakes every Hugo warning fatal,not just render-target collisions. The upside is that a silent
page-overwriting collision can never ship. The cost is that a future Hugo
release which introduces a new warning category will break the build until
someone fixes it — including on
main, and including the deploy path. That isarguably correct behaviour, but it is a standing commitment to keeping the
warning backlog at zero forever, and this repo has just spent real effort
getting it there.
Option B (grep for the specific warning) avoids that commitment at the cost of
a brittle text match. Option C is the status quo.
Not blocking on this — moving to #23 next. Answer whenever; the work is a small
change to
script/lintonce you pick.option a approved. dumb question, shouldn’t have been asked.
Recorded: option (a),
script/lintfails on a render-target collision. One small reviewed change onnextwhen a slot frees.Model: opus-5-5
Plan, building option (a) as approved: Hugo's own
--panicOnWarningon the lint build. One branch offnext, one PR tonext.Dockerfile.lint: the lint step becomeshugo --minify --printPathWarnings --panicOnWarning.--printPathWarningsstays, since it is what makes Hugo report two pages writing the same output file;--panicOnWarningturns that report, and any other Hugo warning, into a failed build. The header comment says so.script/lintheader comment: the lint fails on any Hugo warning, including two pages that write the same output path.README.md: thescript/lintbullet under Entrypoints says the same.TODO.md: a short Completed Steps entry, and this item removed from Blocked.script/testand the deploy workflow are unchanged: only the lint is strict.Before opening the PR, on a scratch copy that is never committed: two pages that render to the same path (for example two files under
content/with the sameurlin their front matter) makescript/lintexit non-zero, and with them removedscript/lintandscript/checkpass on the real site. The PR body gives that recipe in two lines so the reviewer can repeat it. If the pinned Hugo does not stop on that warning under--panicOnWarning, the fallback is to fail the lint step when its output carries Hugo's duplicate target paths warning, stated on the PR.Model: opus-5-5
Built as planned in #46: the lint step runs with
--panicOnWarning, and Hugo stops on its own duplicate target paths warning, so no fallback was needed. The PR has the steps to repeat the check. They include a one-line scratch page layout, because the theme has no layout for ordinary pages.Model: opus-5-5