Troubleshooting
When something goes wrong, run a clean production build first and read from the first error; the ones after it are usually cascades:
An npm, PostCSS, Autoprefixer or browser-asset download step in the log means upstream Docsy’s process has crept into the configuration. A consuming OINK build is one Hugo command.
The four tables below are organized as symptom → cause → fix. Find the symptom row; there is no need to read from the top.
Build
| Symptom | Cause | Fix |
|---|---|---|
| The build demands a newer Hugo | The standard build is installed rather than Extended, or the version is below 0.160.1 | hugo version output must contain extended. With several Hugos installed, check PATH and any version pinning before installing another |
module "github.com/pgsty/oink" not found |
The theme did not resolve | Hugo Module: check hugo mod graph, go.mod, go.sum, and any stray workspace or replace. Submodule: does CI run git submodule update --init before Hugo. Archive / clone: theme: must match the directory name under themes/ |
| Module download hangs or times out | The Go module proxy is unreachable | Hugo pulls modules through Go, so GOPROXY applies. In mainland China, export GOPROXY=https://goproxy.cn,direct; in an isolated environment, use an offline archive or commit themes/oink/ |
{.cards}, {.steps}, {caption=…} appear as literal text |
The site has not enabled Goldmark block attributes | The three settings below must be in the site’s own hugo.yml; Hugo does not merge a theme’s markup configuration |
An image with an attribute line is wrapped in <p> and the caption does nothing |
wrapStandAloneImageWithinParagraph: false is missing |
As above; add all three together |
| Inline HTML is escaped into text | renderer.unsafe: true is missing |
As above |
\(…\) $$…$$ display literally |
The site has not enabled Goldmark passthrough | See Math; math: true is not the switch |
shortcode "tabs" must be closed or self-closed |
A {{< tabs >}} has no matching {{< /tabs >}} |
The error carries file:line:column; add the closing marker there |
template for shortcode "tabs" not found |
The body calls a shortcode that does not exist, or quotes shortcode syntax without escaping it | Documentation that explains shortcode syntax must escape it: add /* and */ inside the opening and closing markers so Hugo treats it as text rather than a call. A misspelled name is simply corrected |
... attributes: unknown attribute "witdh" at ... |
An attribute-line key is misspelled or not permitted | An attribute line accepts that component’s allowed keys plus class, data-* and aria-*; style and on* always fail the build. The allowed keys are in the error’s parentheses |
shortcode "field": unsupported parameter "colour" at ... |
A shortcode parameter name is wrong | A component parameter — a shortcode parameter or an attribute-line key — always fails the build and never degrades silently. The error is always “which shortcode → which parameter → which file and line” |
invalid params.ui.page_width "widee" (allowed: normal | wide | full) -- using "normal" |
A configuration or front matter value is not one of the accepted ones | Configuration degrades instead of stopping, so one typo does not serve HTTP 500 on every URL under hugo server. The message names the key, the value and the fallback used. Build with --panicOnWarning and it cannot ship |
| A page setting has no effect and nothing is reported | The key was written inside a ui: block in front matter |
Page keys sit at the top level of the front matter — the site key with ui. dropped. A ui: block there is read by nobody and reported by nobody; see Page parameters |
| The build passes but production is missing something | A WARNING nobody read | Add --panicOnWarning to the build command. An invalid configuration value, a missing required giscus key, an unsupported comments.type and Hugo’s deprecation notices are all warnings |
The three Goldmark settings:
The two commonest shortcode errors look like this; note the trailing
file:line:column:
Language
| Symptom | Cause | Fix |
|---|---|---|
| A translated page does not appear | Four possibilities, in order | ① hugo.yml has languages.zh with a weight; ② the filename is page.zh.md, with zh lowercase; ③ the translation’s front matter has no draft: true and no future date; ④ routing metadata matches the source file |
| Switching language lands on the home page | Hugo found no translation | This is by design: with no translation it falls back to the target language’s home page. Landing on the corresponding page requires that translation file to exist |
| An anchor link opens the page but does not scroll | The translated heading text differs, so the generated ID does too | Write the English ID explicitly on the translated heading: ## 安装 {#installation}. Where a heading contains a shortcode or inline HTML, do not guess the ID from the text — read the English page’s rendered HTML |
| Menus / home page sections are untranslated | They are not in pages but in configuration and data files | Menus are in languages.<lang>.menus, home sections in data/home/<lang>.yaml, interface strings in i18n/<lang>.yaml — see Languages |
A Chinese page’s hreflang points at the English home page |
That page has no English counterpart | Add the English page, or accept the fallback: it doubles as a probe for whether Hugo recognized the pairing |
Search
| Symptom | Cause | Fix |
|---|---|---|
| A search box that never returns results | No index was generated | With params.offline_search: true, the output root should have offline-search-index.<language>.json, one per language. Its absence means it is not enabled |
| The index file 404s | A wrong baseURL |
On a subpath deployment, a wrong baseURL is the commonest cause of a 404 index. Look in the browser’s network panel to see where it fetches the index — see Deploy |
Search fails under hugo server but works in a build |
The site turned the preview index off | params.offline_search_on_serve defaults to true, so preview matches production; an explicit false skips index generation during preview — remove it or set it back to true |
| Chinese queries find nothing | Usually not a tokenization problem | A CJK query uses the theme’s substring fallback. First confirm the Chinese page’s content reached the Chinese index (open offline-search-index.zh.json), then consider tokenization |
| A new page is not found while old ones are | The index is build output | Rebuild. Under hugo server, wait for the rebuild after editing |
params.search.algolia requires explicit appId, apiKey, and indexName values |
The three Algolia keys are incomplete | All three must be given explicitly; the theme will not use another project’s DocSearch credentials. If Algolia is not wanted, delete the block |
| The command palette finds no content | It and full-text search are two things | With the index unavailable the palette still opens, saying so, while page actions and commands work as usual — see Command palette |
Platform
| Symptom | Cause | Fix |
|---|---|---|
| A 404 or missing styles on GitHub Pages | A project site’s URL carries the repository path and baseURL does not |
Use --baseURL "${{ steps.pages.outputs.base_url }}/" from the workflow rather than hard-coding it. The full workflow is in Deploy |
| “Last modified” and contributors are empty on GitHub Pages | The checkout is shallow | Add fetch-depth: 0 to actions/checkout: enableGitInfo needs the full history |
| A Cloudflare Pages build says Hugo is too old | The build image’s default Hugo is older than the theme requires | Set HUGO_VERSION in both the Production and Preview environments, and set SKIP_DEPENDENCY_INSTALL=1 |
| The host’s build cannot fetch the theme | The build environment has no Go | Hugo Modules need Go. Where a platform does not provide it, use a submodule or commit themes/oink/ |
| CI output differs from local | go.work took part in the CI build |
Set GOWORK: off and HUGO_MODULE_WORKSPACE: off in CI so it reads only the version pinned in go.mod |
| A preview deployment got indexed | The preview was built in the production environment too | Do not pass --environment production for previews; a non-production build carries noindex and Disallow: / — see Analytics and SEO |
| macOS reports too many open files | Live preview watches more files than the shell limit allows | Exclude generated and irrelevant directories from the watch first — usually the real cause — and only then consider ulimit -n |
| Slow, or missed changes, under WSL | Working across a Windows mount point | Let Hugo work on paths inside the Linux filesystem; cross-filesystem change notification and permission behaviour break live reload |
| Bootstrap / Font Awesome / Lunr / Mermaid assets are missing | An incomplete distribution | Do not paper over it with a CDN URL. Confirm assets/third_party/, assets/js/third_party/, static/webfonts/ and VENDOR.json are all present, and re-fetch the same pinned version if one really is missing |
Checks a site can run
Beyond the build itself, a site can run these. The first two work on any OINK site; the rest are this repository’s npm scripts, and another site runs the equivalent.
What each of the six covers:
test:base— builds once, then runs the Markdown style, translation parity, rendered Markdown and link checks.test:hugo-build— build assertions: blog metadata, RSS, content components, and a deprecation-free build.test:md-output— byte-level golden comparison of the Markdown andllms.txtoutput. Changing a component’s Markdown shape fails here.test:alt-site— builds once per alternate configuration intests/fixtures/*.yml, confirming the combinations still come up.test:favicons— golden comparison of the head output.test:release-pin-contract— whether the version the site advertises matches the one pinned ingo.mod.
Browser behaviour is a separate suite: npm run test:browser runs the
Playwright accessibility (axe WCAG AA), responsive shell, keyboard navigation,
content component, code block and scenario component suites in turn.
check-output-security.py lives in the theme repositoryIt sits under the theme’s bin/, is a product-level trust check any OINK site
can run, and depends on no site test framework. Clone the theme repository and
point it at your own public/; the arguments and usage are in
Verifying an offline build.
Diagnostic habits
For problems the tables do not cover, dig along these lines:
- Reproduce with a pinned Hugo Extended version rather than judging in an environment where the version floats.
- Clear
public/andresources/_genand rebuild, to rule out stale caches. - Compare the development and production configuration layers; many production-only problems are environment differences.
- Read the first error, not the last.
- Separate “theme behaviour” from “site override” with a minimal page: isolate the suspect content on its own page and re-enable site overrides in batches until one is implicated.
- Look at the failing page’s browser console and network panel, especially the paths of any 404 resources.
Getting help
Opening an issue with these saves a round trip: the Hugo version (the full
hugo version output), the theme version (hugo mod graph | grep oink), the
first complete error, and a minimal page or site that reproduces it.
- Theme and documentation issues: https://github.com/pgsty/oink/issues
- Issues with this site’s content: https://github.com/pgsty/oink.pgsty.com/issues
- Upstream Docsy compatibility discussion: https://github.com/google/docsy/discussions
Related
- Local preview — clean builds, clearing caches, containers and workspaces
- Deploy —
baseURL, the checklist and rollback - Upgrade — problems an upgrade introduces, and the migration toolkit
- Search — index scope, ranking and Algolia
- Languages — language configuration and the anchor alignment process