Troubleshooting
Doctor output, JS-rendered SPAs, thin pages, the content density gate, and the most common errors.
If pinax add worked but your agent gets unhelpful answers, the problem
is usually one of three things: thin pages from a JS-rendered site, a
manifest that’s gone stale, or a search query that’s hitting noise. This
page walks each one.
Run pinax doctor
pinax doctor stripe
doctor re-scans the manifest and reports drift since the last refresh:
page-count delta, mean prose length per page, fraction of pages that look
empty (under 80 words), broken section anchors. Use it whenever queries
suddenly return junk.
For machine-readable output:
pinax doctor stripe --json
For every manifest at once, omit the name.
JS-rendered docs (SPAs)
Pinax extracts the static HTML the server sends. Pure SPA shells - most React-router-only docs sites with no SSR, ReadMe.io v2, some Mintlify configurations - produce one-line pages that say “Loading…” and nothing else.
From v0.5, Pinax detects this at the content-density preflight and automatically escalates to a JS renderer:
# Get a free API key first (no credit card, personal 500 RPM quota)
export JINA_API_KEY=jina_... # https://jina.ai/reader
pinax add https://docs.mono.co/docs
# > site is a JavaScript SPA - will route through renderer 'jina' (~1m16s for 82 pages).
# > renderer 'jina' rescued the site - manifest will route page fetches through it.
The renderer is Jina Reader. Pinax is BYO key - see Configuration → JS renderer for why (extractable binaries, shared quota, ToS) and the one-line setup.
The chosen renderer is written into the manifest, so pinax serve and
the get_page MCP tool route through it too. You need JINA_API_KEY in
your MCP client’s server-launch env as well - see any of the
client pages for the
env block shape.
Flags on pinax add:
| Flag | Default | What it does |
|---|---|---|
--renderer=auto | (on) | escalate to Jina Reader if the site is a JS SPA |
--renderer=jina | - | same as auto, kept for explicit selection when more renderers exist |
--renderer=off | - | refuse SPA sites, never send URLs to a third-party service |
--render-concurrency=N | 8 | workers inside the renderer (combined with a 400 RPM cap, ~75s per 500-page site) |
If your target is a static site returning shells for other reasons
(broken SSR, edge cache warm-up), try --no-preflight to force the
crawl and let pinax doctor flag thin pages after the fact:
pinax refresh <name> --rebuild-index
The content-density preflight
pinax add runs a one-shot preflight on the candidate URL before crawling:
it fetches the homepage, strips chrome, and checks the prose ratio. If the
ratio is too low it refuses to index, with a message naming the threshold.
Bypass it when you know better:
pinax add <url> --no-preflight
pinax doctor will still flag thin pages after the fact.
”I added it but search_pages returns nothing”
Three things to check, in order:
- Did
pinax addactually finish?pinax listshould show a page count0.
- Is your query a token-AND substring?
payment intentwill match pages containing bothpaymentandintent. If neither token appears, the fuzzy fallback kicks in but it’s intentionally narrow. - Are you scoping correctly? In a unified server,
search_pageswith nodocsarg searches across every manifest. Passdocs: "stripe"to narrow.
Errors you might see
| Message | What it means |
|---|---|
preflight: density below threshold | The homepage looked like an SPA shell. Set JINA_API_KEY and rerun, or --no-preflight. |
JINA_API_KEY not set; manifest not written | You hit a JS SPA without a renderer key. Follow the 3-step hint the CLI printed. |
RENDERER_UNAVAILABLE (from get_page) | The MCP server is missing JINA_API_KEY in its launch env. Add it and restart the client. |
RENDERER_FAILED (from get_page) | Jina Reader errored (invalid key, rate limit, upstream 5xx). Check pinax serve stderr. |
manifest <name> already exists | Use pinax refresh <name> instead, or pinax remove <name> and re-add. |
discovery: no llms.txt, no sitemap, BFS failed | The site has no machine-readable index and links are JS-only. Try --renderer=auto. |
get_page: 404 | A URL drifted out of the docs site. Re-run pinax refresh <name>. |
cache: WAL checkpoint failed | ~/.pinax/cache.db is on a filesystem without proper locking. Move it. |
Most everything else surfaces with a context line; copy the full output into a GitHub issue with the URL you ran against.
Reset
The nuclear option, when you want a clean slate:
pinax cache clear
rm -rf ~/.pinax/servers/<name>
pinax add <name>
You won’t lose anything except indexed manifests - the catalog is compiled into the binary.