How I Accidentally Broke My Docs Site 6 Ways and Fixed Them All in One Afternoon

By Joe Manis - April 6, 2026

 

Also published at info.manitec.pw/blog/docs-fixes


There’s a certain kind of programmer satisfaction that comes not from building something shiny, but from systematically destroying and then resurrecting your own infrastructure in a single sitting. Today was that day.

My docs site — info.manitec.pw — is built with MkDocs Material and deployed to GitHub Pages via a CI workflow. It’s been “working” for weeks. Except it wasn’t really working. It was appearing to work while quietly accumulating problems like a storage unit nobody opens.

Here’s every bug, why it happened, and how I killed it.


Bug #1: Task Snippets Were Silently Empty

I built a system where each project page auto-pulls open GitHub Issues from a private tasks repo and renders them as a live task list using pymdownx.snippets. The Python script ran in CI, wrote the markdown files, everything looked fine.

Except the pages were blank. No errors — just empty sections where tasks should be.

Why: pymdownx.snippets resolves --8<-- include paths relative to the docs/ directory by default. My generated files lived at meta/tasks/ — the repo root — which snippets had no idea about.

Fix:

# mkdocs.yml
- pymdownx.snippets:
    base_path:
      - .       # repo root
      - docs    # docs directory

Two lines. Thirty minutes of confusion. Classic.


Bug #2: CI Would Nuke Itself if the Tasks Repo Didn’t Exist

The task-generation script called the GitHub API for a private repo (Manitec-Tasks). If that repo didn’t exist — or the token lacked the right permissions — the script threw an unhandled exception and crashed the entire deploy pipeline.

Two problems hiding in one.

Problem A: The workflow only had contents: write permission. The Issues API needs issues: read.

# .github/workflows/deploy.yml
permissions:
  contents: write
  issues: read   # ← this was missing

Problem B: No graceful fallback. A 404 or 403 from the API was a hard crash instead of writing an empty snippet.

if resp.status_code == 404:
    print(f"INFO: repo not found for '{slug}' — writing empty snippet.")
    return []
if resp.status_code == 403:
    print(f"INFO: 403 for '{slug}' — writing empty snippet.")
    return []

Now if the tasks repo isn’t ready, the build keeps going and renders “No open tasks” instead of dying.


Bug #3: The Theme Was Fighting My Own CSS

mkdocs.yml had primary: deep purple and accent: indigo from Material’s built-in palette. My custom cyberpunk.css was simultaneously trying to override everything with neon cyan, purple, and pink. Two systems wrestling in the cascade and neither was fully winning.

Fix: surrender the palette to Material and let the CSS own the aesthetics.

theme:
  palette:
    - scheme: slate
      primary: black
      accent: cyan

Neutral base. Custom CSS takes it from there. No more cascade wars.


Bug #4: Neon Glows Rendering Against the Wrong Background

The cyberpunk neon effects looked great in my head. In the browser they looked washed-out because the page background was Material’s default dark slate instead of the true near-black (#0a0a0f) I wanted.

The --dark-bg CSS variable was defined but never applied to the actual page surfaces. Defining a variable and using it are two different things.

.md-main,
.md-header,
.md-tabs,
.md-sidebar,
[data-md-color-scheme="slate"] {
  --md-default-bg-color: #0a0a0f;
  background-color: #0a0a0f;
}

The neon glows properly now.


Bug #5: Custom Domain Reverting on Every Deploy

This one bites a lot of MkDocs users. I had info.manitec.pw set as a custom domain in GitHub Pages settings. After every deploy it reverted back to manitec.github.io/Manitec-Dashboard/.

Why: mkdocs gh-deploy rebuilds the gh-pages branch from scratch on every run. GitHub Pages reads the custom domain from a CNAME file in the branch root. If that file isn’t in your source docs/ folder, it gets wiped on every deploy.

Fix — two parts:

1. Create docs/CNAME containing just your domain:

info.manitec.pw

2. Update site_url in mkdocs.yml:

site_url: https://info.manitec.pw/
Cloudflare DNS tip: Point infomanitec.github.io as a CNAME with the proxy off (grey cloud). GitHub Pages handles HTTPS itself — proxying through Cloudflare at the same time causes certificate conflicts.

Bug #6: Stale URLs and a Dead Nav Link

A full docs audit turned up three quiet wrongnesses:

  • HexBot listed with chat.manitec.pw — that’s ManiBot’s URL. HexBot lives at hex.manitec.pw.
  • ManiBot listed with stack “Python” — it’s Next.js 15, Vercel AI SDK, Groq, and Neon.
  • A Chatbot row in the projects table linked to projects/chatbot.md — a file that doesn’t exist. Silent 404.

None of these broke the build. They just made the docs quietly wrong, which is somehow worse.


The Lesson

Docs sites feel low-stakes until they’re the thing you hand someone when they ask “where can I learn about your projects?” These fixes took one afternoon but the bugs had been silently accumulating for weeks. An occasional audit — even just reading your own docs top-to-bottom — catches a surprising amount.

The full Manitec empire docs live at info.manitec.pw — now actually working as intended.


Built by Joe — Manitec.pw