Remove unused includes and fail the build on broken include references#25392
Conversation
Delete 10 orphaned files under content/includes that are no longer referenced by any page via the include shortcode: - aci-ecs-eol.md, compose-eol.md, dev-envs-changing.md, dockerfile-labs-channel.md (stale EOL/status callouts) - buildx-v0.10-disclaimer.md, experimental.md, deploy.md, guides-get-docker.md, open-terminal.md (orphaned snippets) - labspace-quickstart.md (empty) Also fix two broken include references: - scout-early-access.md was deleted in 737ad3c but two environment integration pages still included it; remove the dangling lines. - reference/compose-file/develop.md included compose/develop.md, which does not exist; point it at the real file, compose/services-develop.md. Every include file is now referenced, and every reference resolves. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The include shortcode previously called readFile directly, which renders nothing when the target is missing instead of failing. That let renamed or deleted snippets linger as silent no-ops (for example the stale scout-early-access.md and compose/develop.md references). Check fileExists first and errorf with the shortcode position when the target is missing, mirroring the file/files shortcodes. Verified against Hugo 0.163.0: valid includes still render; a missing target now fails the build with the offending file and line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for docsdocker ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
This PR is a well-scoped, correct cleanup. All changes are in added lines only and the implementation is sound.
include.html shortcode hardening: The new fileExists + errorf guard mirrors the existing pattern in file.html and files.html. The path includes/foo.md is consistent with the pre-existing readFile "includes/foo.md" call that has worked correctly for the lifetime of the repo (no includes/ directory exists at the project root, confirming Hugo resolves these relative to content/). The PR's claim of tested behavior against Hugo 0.163.0 is consistent with this.
Broken reference fixes: compose/services-develop.md exists at content/includes/compose/services-develop.md ✓. The scout-early-access.md references are fully removed with no remaining references anywhere in the repo ✓.
Removed includes: All 10 deleted files are stale/orphaned snippets — none are pages, so no redirect aliases are needed.
No documentation style issues, no missing redirects, no vendored file edits, no AI-isms in the changed lines.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
One logic issue found in the new include.html shortcode. The removed files and fixed include references look clean.
| {{ if not (fileExists $filePath) }} | ||
| {{- errorf "include shortcode: file %q not found: %s" $filePath .Position -}} | ||
| {{ end }} | ||
| {{ readFile $filePath | safeHTML }} |
There was a problem hiding this comment.
[MEDIUM] readFile is called unconditionally — missing file still reaches readFile even after errorf
The new include.html shortcode places {{ readFile $filePath | safeHTML }} outside the if/end block, so it runs unconditionally regardless of whether fileExists returns true or false:
{{ if not (fileExists $filePath) }}
{{- errorf "include shortcode: file %q not found: %s" $filePath .Position -}}
{{ end }}
{{ readFile $filePath | safeHTML }} ← always executed
In Hugo, errorf logs the error and marks the build as failed, but does not halt template execution — it returns an empty string and execution continues. This means when a file is missing: (1) errorf fires and marks the build as failed, (2) readFile is still called on the missing path (returns an empty string silently). The build does fail, but the template continues executing unnecessarily.
The conventional safe pattern in Hugo is to gate readFile inside the else branch:
{{ if fileExists $filePath }}
{{ readFile $filePath | safeHTML }}
{{ else }}
{{- errorf "include shortcode: file %q not found: %s" $filePath .Position -}}
{{ end }}
This ensures readFile is only called when the file actually exists, matching the stated intent of the PR.
What
Cleans up
content/includes/and hardens theincludeshortcode so this class of issue can't recur silently.Remove 10 unused include files
These snippets are no longer referenced by any page via the
{{%/* include */%}}shortcode (the_index.mdcascade setsrender: never, so includes are only ever pulled in by that shortcode):aci-ecs-eol.md,compose-eol.md,dev-envs-changing.md,dockerfile-labs-channel.md— stale EOL/status calloutsbuildx-v0.10-disclaimer.md,experimental.md,deploy.md,guides-get-docker.md,open-terminal.md— orphaned snippetslabspace-quickstart.md— empty fileFix two broken include references
scout-early-access.mdwas deleted in 737ad3c ("scout: remove early access callout") but two environment-integration pages (sysdig.md,cli.md) still included it. Removed the dangling lines.reference/compose-file/develop.mdincludedcompose/develop.md, which doesn't exist; the file iscompose/services-develop.md. Repointed the include at the real file. (This is also whyservices-develop.mdlooked unused — it was, due to the typo.)After this, every include file is referenced and every reference resolves.
Fail the build on broken include references
The shortcode previously called
readFiledirectly, which renders nothing when the target is missing rather than failing — exactly how the two stale references above went unnoticed. It now checksfileExistsanderrorfs with the shortcode position when the target is missing, mirroring thefile/filesshortcodes.Testing
Verified against the project's Hugo (0.163.0 extended) in an isolated minimal site:
ERROR include shortcode: file "includes/<name>" not found: "<file>:<line>:<col>", naming both the missing file and the offending shortcode location.scripts/lint.shpasses clean on the edited content pages.🤖 Generated with Claude Code