Symptom: Search modal opens but returns "No results found" for any query.
Debugging Approach:
- Used Playwright to navigate to the deployed site
- Checked browser console logs - found 404 errors for
/pagefind/pagefind.js - Compared CI workflow (
ci.yml) with deploy workflow (deploy.yml) - Found that
npm install -g pagefindwas in CI but not in deploy
Root Cause: The pagefind CLI must be installed before running the md-book binary because:
md-bookcallsPagefindBuilder::build()which executespagefind --site <output_dir>as a subprocess- Without the CLI installed, the subprocess silently fails (error is caught with
eprintln!) - The build continues but no
/pagefind/directory is created
Fix: Add npm install -g pagefind step to deploy workflows before generating the site.
Lesson: When a build tool depends on external CLIs, ensure they're installed in ALL workflows that run the tool, not just the CI workflow.
Symptom: Links in SUMMARY.html content area pointed to .md files (e.g., href="page.md") instead of .html.
Debugging Approach:
- User provided the rendered HTML showing the issue
- Sidebar navigation was correct (
.html) but content links were wrong (.md) - Traced markdown processing in
core.rsto find where HTML is generated
Root Cause: The markdown crate converts markdown to HTML but doesn't modify internal link extensions. The SUMMARY.md file contains links like [Page](page.md) which get rendered literally.
Fix: Added post-processing function convert_md_links_to_html() that:
- Finds
href="...md"patterns in the HTML output - Skips external links (http://, https://, mailto://, //)
- Converts internal
.mdlinks to.html
Lesson: Markdown-to-HTML converters typically don't modify link targets. If you need link transformation, add post-processing.
Symptom: PR #18 with Rust dependency updates failed CI.
Root Cause: warp 0.3.5 → 0.4.2 includes breaking API changes to WebSocket module.
Lesson: Dependabot groups dependencies together, which can cause PRs to fail when any dependency has breaking changes. Consider:
- Reviewing changelogs before merging grouped updates
- Using separate groups for major vs minor/patch updates
- Adding version constraints in Cargo.toml for dependencies with unstable APIs
The PagefindBuilder used eprintln! for errors instead of failing the build:
if let Err(e) = pagefind.build().await {
eprintln!("Search indexing failed: {e}");
}This allowed builds to succeed without search functionality. Consider whether errors should be fatal or logged.
Added verification step in deploy workflows:
if [ -d "dist/pagefind" ]; then
echo "✓ Pagefind search index created successfully"
else
echo "✗ ERROR: Pagefind search index not found!"
exit 1
fiThis catches issues before deployment rather than discovering them in production.
Playwright's MCP tools are excellent for debugging deployed web apps:
- Navigate to URLs
- Take screenshots
- Check console logs
- Interact with elements Much faster than manual browser debugging.
The first debugging step for frontend issues should be checking console logs:
// Console showed:
Failed to initialize Pagefind: TypeError: Failed to fetch dynamically imported moduleThis immediately pointed to missing files rather than code bugs.
-
Don't assume CI = Deploy: Just because CI passes doesn't mean deploy will work - they may have different dependencies installed.
-
Don't rely on default link handling: Markdown converters won't automatically adjust links for your build system.
-
Don't group all dependencies together: Breaking changes in one dependency can block updates to others.
-
Don't silence subprocess errors: If an external tool fails, the build should probably fail too.