Overview

Most Quartz build failures are silent: the build finishes with exit code 0 but produces wrong output. --verbose surfaces per-page warnings, link resolution failures, and plugin errors that the default output suppresses. This page covers the flag, the most common error classes, how the .quartz-cache/ directory works, and the patterns that recover a broken build.

Run --verbose before reporting a build problem

The default build prints one line per emitter. --verbose prints a line per page and surfaces warnings.

npx quartz build --verbose

Look for lines that contain warn or error. Common verbose output to act on:

  • [warn] Could not find [[some-page]]: a wikilink resolves to nothing; the target page is missing or the slug does not match.
  • [warn] Missing required frontmatter field: title: a page will build but the HTML title falls back to the filename.
  • [error] Duplicate slug: foo: two files resolve to the same output path; one will overwrite the other.

Pipe the output to a file when the build is large: npx quartz build --verbose 2>&1 | tee build.log. Grep for warn and error in the log.

CrawlLinks resolves wikilinks by the shortest unambiguous slug. [[quartz]] resolves to the first page whose slug ends in /quartz. If two pages share the same trailing slug segment, the link is ambiguous and resolves to whichever comes first alphabetically, not the intended target.

Disambiguate with the folder prefix:

[[tooling/quartz]]           # unambiguous
[[tooling/quartz-config]]    # preferred over [[quartz-config]]

--verbose prints each failed resolution with the source file and the attempted target. Fix every warning before deploying. Dead links in the graph produce missing nodes that confuse readers and break backlinks. See quartz-config for markdownLinkResolution options.

Resolve missing frontmatter errors by auditing the content directory

Pages with incomplete frontmatter build but produce degraded output: missing titles, wrong dates, empty tag pages. Run a targeted audit:

# Find files missing a title field
grep -rL "^title:" content/ --include="*.md"
 
# Find files missing a status field
grep -rL "^status:" content/ --include="*.md"

Add the missing fields. The content schema requires title, slug, category, tags, status, last_updated, and summary on every page. Pages that lack slug inherit the filename as the slug, which can produce casing mismatches on case-sensitive file systems.

Clear .quartz-cache/ when output is stale after a plugin change

Quartz caches the parsed content graph in .quartz-cache/ between builds to speed up incremental rebuilds. Changing a plugin’s name, reordering transformers, or installing a new version of Quartz can leave stale cache entries that produce wrong output without any warning.

rm -rf .quartz-cache && npx quartz build

Do this any time a plugin change does not seem to take effect. The cache is safe to delete; Quartz reconstructs it on the next build. Add .quartz-cache/ to .gitignore so it never commits. Check with:

grep ".quartz-cache" .gitignore

Diagnose theme issues by inspecting CSS custom properties

Theme problems (wrong colors in dark mode, fonts not loading) usually trace to one of three causes.

  1. A CSS custom property spelled wrong: open DevTools, pick an element, and confirm var(--secondary) resolves to a hex value. If it shows as empty, the property is missing from the generated stylesheet.
  2. A fontOrigin: "googleFonts" setting blocked by a Content Security Policy. The browser console shows a blocked request to fonts.googleapis.com. Either relax the CSP or switch to fontOrigin: "localFonts".
  3. A component’s .css property using hard-coded hex values instead of CSS variables. The component looks correct in light mode and wrong in dark mode. Fix by replacing hex values with var(--dark), var(--light), etc. See quartz-components for the .css property pattern.

Use the build output directory to verify emitter behavior

After a build, public/ shows exactly what the host will serve. Spot-check it before pushing.

# Confirm CNAME exists and is correct
cat public/CNAME
 
# Confirm sitemap generated
ls public/sitemap.xml
 
# Confirm a specific page built
ls public/tooling/quartz/index.html
 
# Count HTML files to catch a filter removing too many pages
find public -name "*.html" | wc -l

If the HTML count drops unexpectedly, the most common cause is Plugin.RemoveDrafts() matching pages that should have shipped. Check that status: stable is set in the frontmatter of pages that are disappearing. See quartz-plugins for filter plugin behavior.

Recover a fully broken build in four steps

When npx quartz build fails with a hard error and the message is unclear:

  1. Clear the cache: rm -rf .quartz-cache.
  2. Reinstall dependencies: npm ci.
  3. Check Node version: node -v. Quartz requires Node 22. If the version is wrong, switch with nvm use 22.
  4. Run with verbose output and redirect to a log: npx quartz build --verbose 2>&1 | tee build.log, then search the log for the first error line.

Most hard failures are a Node version mismatch or a corrupted node_modules. Steps 1 and 2 fix the majority. See quartz-config for the engines field that pins Node in package.json.