Troubleshooting
This page covers common issues you may encounter when using Accent CMS, along with their causes and solutions. Use the table of contents to jump to the relevant section.
Page Not Found (404)
A 404 response means Accent CMS could not match the requested URL to any content page. The table below lists the most common causes.
| Symptom | Cause | Fix |
|---|---|---|
| Page returns 404 | File not in content directory | Check content.directory in config.yaml points to the correct path |
| Page returns 404 | No recognized index file | Name the file default.md, README.md, or index.md |
| Page returns 404 | Directory has numeric prefix but URL does not | URLs strip numeric prefixes automatically: 01.home/ serves at /home |
| Page returns 404 | Frontmatter published: false | Set published: true or remove the field |
| Page returns 404 | Page status is draft or review | Set dev.show_drafts: true in config.yaml to preview draft pages |
| Page returns 404 | Mismatched URL path | Verify the directory structure matches the expected URL |
| Page returns 404 | Mistyped file extension | Content files must end in .md |
Debugging 404 Errors
- Check loaded pages. Add
?acdbgto any working page URL and inspect theall_pageslist to see every page Accent CMS has loaded. If your page is missing from the list, the problem is in content loading. - Run validation. Use
accent validateto check content integrity across all pages. - Check server logs. The terminal output shows which files are loaded at startup and when content is reloaded.
- Verify config.yaml. Ensure
content.directorypoints to the correct folder (default:./content).
Template Rendering Errors
MiniJinja template errors appear in the server logs and sometimes in the browser as a 500 error page. The table below maps common error messages to their solutions.
| Error Message | Cause | Fix |
|---|---|---|
undefined value | Variable does not exist in template context | Check spelling; use {% if var is defined %} to guard optional variables |
value is not iterable | Trying to loop over a non-list value | Inspect the variable type with {{ debug(var) }} |
template not found: X | Template name in frontmatter does not match a file | Check the template: field and the theme’s templates/ directory |
filter not found: X | Using a filter that does not exist | Check available filters in the Templating Guide |
missing block 'X' | Template extends a base but references an undefined block | Verify block names match between parent and child templates |
cannot extend across engines | Included template uses a different engine | All templates in an inheritance chain must be MiniJinja |
recursion limit reached | Circular template inheritance | Check that no template extends itself directly or indirectly |
Debugging Template Errors
- Use
{{ debug(page) }}in a template to dump the full page context as formatted output. - Use
{{ debug(site) }}to inspect site-level variables. - Add
?acdbgto any page URL to open the built-in debug panel without editing templates. - Enable
dev.debug: truein config.yaml and use{% if dev.debug %}blocks for conditional debug output.
Hot Reload Not Working
Hot reload watches for file changes and automatically refreshes the browser. When it stops working, check the following.
| Symptom | Cause | Fix |
|---|---|---|
| No reload on file save | dev.hot_reload is false | Set dev.hot_reload: true in config.yaml |
| Browser does not refresh | dev.browser_reload is false | Set dev.browser_reload: true in config.yaml |
| Changes take several seconds to appear | Debounce interval too high | Lower dev.debounce_ms (default: 500) |
| Hot reload works but SSE disconnects | Browser lost the SSE connection | Refresh the page to reconnect to /_dev/reload |
| Changes to files outside watched dirs | Watcher only monitors content and theme directories | Restart the server for config changes, or send SIGHUP to reload config |
| File watcher misses changes | Some editors write to a temp file then rename | Most editors work fine; try lowering dev.debounce_ms to 50 |
| Hot reload worked then stopped | Server crashed or was backgrounded | Check the terminal for errors; restart with accent serve |
SIGHUP Config Reload
On Unix systems, you can reload config.yaml without restarting the server:
pkill -HUP accent
If the new configuration is invalid, the server keeps running with the previous configuration and logs the error.
Content Validation Warnings
Accent CMS validates content automatically when pages are loaded. Each validation check and its resolution is listed below.
| Warning | Meaning | Fix |
|---|---|---|
| Missing template | template: references a file not found in the theme | Create the template or change template: to an existing one |
| Broken internal link | A markdown link points to a page that does not exist | Fix the link target URL |
| Invalid date | date: field is not a valid YYYY-MM-DD date | Correct the date format in frontmatter |
| Orphaned page | Page has no parent index page in the hierarchy | Create a default.md in the parent directory |
| Missing required field | Blog template page is missing date | Add a date: field to frontmatter |
| Duplicate index files | Multiple index files in the same directory | Keep one (default.md takes priority, then README.md, then index.md) |
Running Validation
# Validate all content accent validate # Validate with a specific config file accent validate --config prod.yaml # Use in CI (exits with code 1 if problems found) accent validate || echo "Content issues found"
The output groups issues by page with severity labels:
Content Validation Report
=========================
Warnings (2):
/blog/old-post
- Missing template: "legacy-layout" not found in current theme
- Invalid date: "2024-13-01" is not a valid date
Info (1):
/orphaned/deep/page
- Orphaned page: parent "/orphaned/deep" has no index page
Summary: 0 errors, 2 warnings, 1 info across 3 pages
Validation is advisory. Issues are reported but do not block page serving.
Performance Issues
| Symptom | Cause | Fix |
|---|---|---|
| Slow first page load | Cold cache, templates compiling | Normal on the first request; subsequent requests use the cache |
| Slow after content change | Cache invalidated by file watcher | Expected behavior; cache rebuilds on the next request |
| Slow with many pages (1000+) | Large content directory scan | Use pagination, optimize the content hierarchy, or switch to static build |
| High memory usage | Large media cache | Reduce media.cache.max_size_mb in config.yaml |
| Slow image processing | Large images processed on demand | Pre-process images or increase media.cache.max_size_mb |
| Slow template rendering | Complex template inheritance chain | Simplify inheritance; avoid deeply nested includes |
| Slow static build | Processing all pages sequentially | Build times scale with page count; consider splitting large sites |
General Performance Tips
- Use
accent serve --productionfor optimized caching behavior. - Monitor server memory usage and adjust
media.cache.max_size_mbaccordingly. - Use
accent buildfor static output if content does not change frequently. - For sites with thousands of pages, pagination reduces per-request work.
- Keep images at reasonable sizes. Accent CMS processes them on demand, so very large source images increase first-request latency.
Server Seems to Stall After Being Left Idle
If you come back to a laptop after a break – or reconnect after switching networks – and the first page load hangs or the hot-reload browser refresh stops arriving, the cause is usually a connection the server still believes is open.
When a client disappears without closing its connection cleanly (the laptop
slept, Wi-Fi power-save kicked in, the router re-assigned the NAT mapping, the
browser tab crashed), no FIN packet ever reaches the server. Nothing in HTTP
tells the server the peer is gone. Left to the operating system’s default
retransmission timeout, the dead connection can occupy a slot for 16 minutes or
more, and anything the server tries to write to it – a hot-reload event, for
instance – stalls before eventually failing.
accent serve enables TCP keep-alive probes on both its HTTP and HTTPS
listeners to close that window. A connection that goes quiet is probed after 60
seconds, re-probed every 10 seconds, and dropped after three unanswered probes
– so a vanished client is cleaned up in roughly 90 seconds instead of a quarter
of an hour. On HTTPS, where browsers negotiate HTTP/2, the server additionally
sends an HTTP/2 PING every 30 seconds and closes the connection if it is not
acknowledged within 10 seconds.
This is on by default and needs no configuration.
accent serve-static and accent docs serve bind their own listeners and do
not yet enable keep-alive. If you hit an idle stall while previewing a
static build or the embedded docs, the connection can linger for the operating
system’s default timeout – 16 minutes or more – rather than 90 seconds.
Reloading the page opens a fresh connection and clears it.
| Symptom | Likely cause | Fix |
|---|---|---|
| First request after a long idle period hangs, then works on reload | The browser reused a connection the network had already discarded | Expected; the browser opens a fresh connection. Reload once |
| Hot-reload stops refreshing the browser after sleep | The SSE connection was severed without either side noticing | Reload the page to re-establish the event stream |
| Server log warns that TCP keep-alive could not be enabled | A restrictive sandbox or container refused the socket option | Harmless for correctness; dead connections are reaped on the OS default schedule instead. Check container security policies if you need faster detection |
If a stall persists for more than a couple of minutes after a reload, it is not
a stale connection – check the “Performance Issues” section above, and note
that on macOS the operating system’s App Nap can throttle a backgrounded
terminal running accent serve. Keeping the terminal window visible, or
running the server under a process manager, avoids that.
Markdown Rendering Issues
| Symptom | Cause | Fix |
|---|---|---|
| Frontmatter shows as text | --- markers not at the very start of the file | Ensure --- is on line 1 with no leading whitespace or BOM |
| HTML in markdown not rendering | HTML is escaped by default | Use raw HTML blocks with a blank line before and after the HTML |
| Code block not highlighted | Language not specified | Add the language after the opening ``` (e.g., ```rust) |
| Table not rendering | Missing header separator row | Add a ` |
| Shortcode not rendering | Syntax error in shortcode | Check the shortcode syntax: {%- name "arg" %} |
| Sections not splitting | Wrong marker syntax | Use exactly ---section: name--- on its own line |
| Emoji shortcodes not rendered | Not a supported feature | Use Unicode emoji characters directly instead |
| Footnotes not rendering | Footnote syntax incorrect | Use [^1] for the reference and [^1]: text for the definition |
Frontmatter Troubleshooting
The most common rendering problem is frontmatter appearing as plain text. The --- delimiter must be:
- On the very first line of the file (line 1, column 1)
- Exactly three hyphens with no trailing spaces
- Not preceded by a byte-order mark (BOM) or blank line
If you copy content from another system, check for invisible characters at the start of the file.
Plugin Errors Free
| Error | Cause | Fix |
|---|---|---|
| Plugin not loading | Plugin runtime disabled | Set plugins.enabled: true in config.yaml |
| Plugin crash (fuel exhaustion) | Plugin exceeded computation limit | Increase the fuel limit or optimize plugin code |
| Plugin API version mismatch | Plugin built for a different API version | Rebuild the plugin against the current Accent CMS SDK |
| Plugin not found | Missing from the plugin directory | Run accent plugin install <url> |
| Plugin compile error | Invalid WASM binary | Verify the .wasm file is valid; rebuild from source |
| Plugin timeout | Plugin took too long to respond | Check for infinite loops; increase the timeout if the work is legitimate |
Plugin Debugging
# List installed plugins accent plugin list # Check plugin info accent plugin info <name> # Install a plugin accent plugin install <url>
Plugins run in a sandboxed WASM environment with bounded fuel (computation steps). If a plugin exhausts its fuel, Accent CMS terminates it and logs the error. Increase the fuel limit in config.yaml if the plugin does legitimate heavy computation:
plugins: fuel_limit: 200000 # default: none (no limit)
Build Errors
| Error | Cause | Fix |
|---|---|---|
| “Base URL required for sitemap” | site.url not set | Add site.url to config.yaml or pass --base-url |
| Output directory not writable | Permission issue | Check directory permissions with ls -la |
| Pagination files not generated | content.limit not set | Add content.limit to collection frontmatter |
| “Template not found” during build | Theme missing a required template | Check that the theme directory contains all referenced templates |
| Build produces empty output | No content files found | Verify content.directory points to a directory with .md files |
| Feed not generated | feed.enabled is false or no pages have date | Enable the feed in config.yaml and add date: to page frontmatter |
Build Command Reference
# Basic static build accent build --output ./public --base-url https://example.com # Build with a specific config accent build --config prod.yaml --output ./dist # Dry run (validate without writing files) accent build --output ./public --dry-run
Configuration Errors
| Error | Cause | Fix |
|---|---|---|
| “Failed to parse config.yaml” | YAML syntax error | Check indentation and quoting; use a YAML linter |
| “Unknown field: X” | Typo in a config field name | Check the Configuration Reference for valid fields |
| “Invalid theme: X” | Theme directory does not exist | Verify theme.directory and theme.name in config.yaml |
| “Port already in use” | Another process is using the port | Change server.port or stop the other process |
| “Content directory not found” | Path does not exist | Create the directory or fix the path in content.directory |
| Config reload rejected (SIGHUP) | New config has validation errors | Check server logs for the specific error; the previous config remains active |
Validating Configuration
Before deploying, verify your configuration loads correctly:
# The server will fail fast if config is invalid accent serve --config prod.yaml # Validate content with a specific config accent validate --config prod.yaml
Common YAML mistakes:
- Incorrect indentation. YAML uses spaces, not tabs. Nested fields must be indented consistently.
- Unquoted special characters. Values containing
:,#,[,],{,}must be quoted. - Boolean confusion.
yes,no,true,falseare booleans in YAML. Quote them if you mean a literal string.
Getting Help
When the sections above do not resolve your issue, use these resources.
Self-Service Debugging Tools
- Content validation: Run
accent validateto scan all pages for common problems. - Debug panel: Add
?acdbgto any page URL to inspect the full template context, page hierarchy, validation issues, custom frontmatter, config, search, and cache stats. Use?acdbg=rightor?acdbg=floatfor alternative panel positions. - Server logs: Check terminal output for error messages, warnings, and content loading details.
- Version info: Run
accent --versionto display the version, edition, and license status.
Asking and Reporting
If you have found a bug or need help with an issue not covered here:
- Check the server logs and the debug panel for error details.
- Note your Accent CMS version (
accent --version). - Prepare a minimal reproduction if possible (a small config.yaml and content directory that triggers the problem).
- Take it to the forum – the same three items make a question answerable as well as a bug actionable. File it on the issue tracker if you are confident it is a defect.
If the missing piece is a capability rather than a fix, check the Hub before building it: it is the signed registry of plugins, themes, and starter templates, and someone may already have published what you need.
Common Quick Fixes
| Problem | Quick Fix |
|---|---|
| Everything broke after an update | Check the CHANGELOG for breaking changes |
| Pages load but look unstyled | Verify the theme directory exists and theme.name matches |
| Server starts but no pages load | Check content.directory in config.yaml |
| Cannot access the site from another machine | Change server.address from 127.0.0.1 to 0.0.0.0, and set ACCENTCMS_DEV_CERT_SANS to the address the other machine will use (see below) |
| Certificate warning on first visit | Expected: dev mode serves HTTPS with a self-signed certificate. Proceed anyway; it is cached, so the warning appears once. --no-tls serves plain HTTP |
| Certificate name mismatch from another machine | The certificate covers localhost and 127.0.0.1 only. Set ACCENTCMS_DEV_CERT_SANS to the address you are visiting |
| Dev features appear in production | Use --production flag to disable dev mode |
HTTPS in dev mode
accent serve binds HTTPS with a self-signed certificate cached under your
platform cache directory, so the browser warning appears on the first visit
and not on every restart.
A wildcard bind (server.address: 0.0.0.0) is the case Accent cannot solve
for you: it does not know which of the machine’s addresses a visitor will
type, so the certificate covers only loopback and a phone or second machine
gets ERR_CERT_COMMON_NAME_INVALID. The server warns about this at startup.
Name the address explicitly:
ACCENTCMS_DEV_CERT_SANS=192.168.1.20 accent serve
Or drop back to cleartext with accent serve --no-tls.