Loading...

Loading...

FAQ

This page collects common errors and their solutions during blog usage. Each problem follows a symptom → cause → solution structure; commands can be copied directly.

1. Cache Not Taking Effect (changes don’t show)

Symptom: after changing config/styles/posts, the built page is still old; or browsers/PWA keep showing the old version.

Cause: three layers of cache stack up — the Hexo incremental cache (db.json), the hexo server memory cache, and browser/PWA Service Worker cache. Rule them out layer by layer, starting from the outermost:

Solution:

# ① first confirm whether it's a build output problem or a browser problem
curl -s http://localhost:4000/ | grep "keyword"   # does the server return old or new?

# ② build cache: hexo clean is the official cleanup (deletes db.json + public + resets internal cache)
#    ⚠️ don't substitute rm -rf public db.json — it doesn't reset hexo's internal cache state
hexo clean && hexo generate

# ③ server memory cache (inside the Docker container): pm2 restart isn't enough, delete db.json
pm2 stop hexo_run && rm -f /app/db.json && pm2 start hexo_run
// ④ browser/PWA cache: after changing JS/CSS you MUST bump the version (-r release), otherwise the SW serves the old version
navigator.serviceWorker.getRegistrations()   // inspect SW in console; unregister before verification

Prevention: use tools/cicd.sh -r to bump the version for JS/CSS changes; -c for content-only changes (see the release flow selection in the Deployment chapter).

2. db.json Permission / Data Cache Conflicts

Symptom:

FATAL Error: EACCES: permission denied, open '/app/db.json'
FATAL Error: EACCES: permission denied, unlink '/app/db.json'

Or: pages go blank after changing source/_data/*.yml data files (site.data.xxx undefined).

Cause: the Docker container runs as root by default; files created in bind-mounted host directories are owned by root, so the host user can’t delete them → EACCES. Blank pages from data files are the Hexo incremental cache misjudging “already cached, unchanged” (the Cache hash updates but the Data model isn’t written).

Solution:

# permissions: fix ownership inside the container
fix_perms() {
    local owner=$(stat -c '%u:%g' /app)
    chown -R "$owner" /app/db.json /app/public/ /app/.cache/
}
fix_perms && hexo clean

# data cache: must delete db.json before generate
rm -f db.json && hexo generate
# container 4000 preview: pm2 stop → rm -f /app/db.json → pm2 start (restart without deleting db is useless)

# root fix: specify a user in docker-compose.test.yml
# services.hexo.user: "${PUID:-1000}:${PGID:-1000}"

Delete db.json before verifying data loading, otherwise you read the old cache and get a false pass.

3. Build Failures (post_link / unknown block tag)

Symptom:

Cannot find post with slug: xxx          # post link broken
Error: Unable to locate template: xxx     # template not found
unknown block tag: xxx                    # custom tag misspelled or registration failed

Cause: the post post_link points to doesn’t exist or its slug changed; {% xxx %} uses an unregistered or misspelled tag; wrong template path.

Solution:

# ① first locate the failing file and line (the build output gives it)
npx hexo generate 2>&1 | grep -A2 "FATAL\|Error"

# ② post_link: confirm the target post exists; use the filename or the front-matter slug
#    this blog uses abbrlink permalinks; use post_link + title for inter-post links
{% post_link post-title %}

# ③ unknown block tag: check whether the tag is registered under themes/matery/scripts/tags/,
#    and whether it was written in inline form ({% tag %} without closing vs {% tag %}...{% endtag %})

# ④ build hangs: when hexo generate outputs nothing, use --debug to watch progress
npx hexo generate --debug

Prevention: after changing scripts under scripts/, always hexo clean before generate (a plain generate may reuse old output — cost an hour of debugging once).

4. Comments Not Showing

Symptom: no comment box at the bottom of posts, or a blank comment area.

Cause: three layers of switches — the global switch, the front-matter switch, and the Waline serverURL config.

Solution:

# ① theme config (userConfig/_config.tmp.yml):
#    find the waline section, confirm enable: true and a correct serverURL
serverURL: 'https://waline.17lai.site'   # comment service address

# ② post front-matter: did it disable comments?
---
comments: true    # false or missing (depends on the template default) both hide comments
---
# ③ verify the service is reachable
curl -sI https://waline.17lai.site | head -3

Note: the comment injection point (postComments) is called in templates — confirm the waline template under layout/_partial/comments/ isn’t commented out; clear caches per section 1 after config changes.

5. Dark Mode Issues (–font-scale / CSS variables)

Symptom: text illegible or colors scrambled after switching to dark; or font sizes off (--font-scale reset).

Cause: the theme implements dark mode with CSS variables ([data-user-color-scheme="dark"]); font sizes are rem-based, scaling with --font-scale. Issues are mostly: CSS variables overridden by hardcoded colors, the font scale modified, or browser zoom preferences interfering.

Solution:

// ① confirm dark variables apply in the console
getComputedStyle(document.documentElement).getPropertyValue('--body-bg-color')

// ② font size issues: check whether the font scale was modified (rem-based, scales with --font-scale)
//    font_size_* series in themes/matery/_config.yml or templates
//    --font-scale is set by JS per browser/user preference; confirm localStorage has no stale leftovers

// ③ style override checks: don't force-override theme variables with !important (breaks lower-layer styles),
//    reference CSS variables with var(--xxx) in custom styles

Principle: custom colors must use CSS variables like var(--card-bg-color) (three-layer architecture: config → Stylus variables → CSS variables), never hardcode #333 (see the Customization chapter).

6. Language Switching Not Working (localStorage)

Symptom: clicking the trad/simp or language switch button doesn’t change the page, or it reverts on refresh.

Cause: the language preference is stored in localStorage; the switching logic reads theme.preference config in the corresponding JS. Not working usually means: JS cached (old version without the feature), localStorage cleared/disabled, or the config switch turned off.

Solution:

// ① check the preference value and config in the console
localStorage.getItem('language')            // language preference (actual key per code)
localStorage.removeItem('xxx')              // clear stale leftovers, then refresh

// ② confirm the switch: the preference section of the theme config
//    translate: Chinese trad/simp conversion (consolidated into preference.translate on 2026-08-16)
//    the legacy footer.translate was removed on 2026-08-10; only preference.translate.enable is read

// ③ still not working → follow section 1 cache troubleshooting (version not bumped, browser running old JS)

Prevention: for config changes affecting JS behavior, release with -r so the version changes (?v=xx updates, browsers fetch the new version).

Appendix: Troubleshooting Order (follow this first)

StepCheckCommand
1build log for errorsnpx hexo generate 2>&1 \| grep -i error
2build output updatedcurl -s site-URL \| grep keyword
3cache cleanuphexo clean && hexo generate
4server memory cachepm2 stop && rm -f db.json && pm2 start
5browser/PWA cacheversion bump (-r) + unregister SW
6actual config valuesgrep key-name userConfig/_config.tmp.yml
Comments
Data Loading...