Troubleshooting
The answers to most failures already live somewhere in these docs — this page indexes them by the symptom you actually see, so you can search by error message.
Quick index
| Symptom | Jump to |
|---|---|
Could not detect a repeating item list | § Not a list |
| API-mode run "succeeds" with zero items | § Zero items |
API: response is not JSON … | § Not JSON |
Blocked by <vendor> (HTTP 403) | § Blocked |
Fields come back null / page looks empty | § Empty shell |
| Detector picked the wrong list (nav, sidebar) | § Wrong list |
| Infinite-scroll endpoint returns 500 | § Scroll 500s |
primary_image is an icon / tracking pixel | § Bad image |
| "Where did my output go?" | § Output |
Could not detect a repeating item list
The generator requires a repeating pattern; an article, profile or dashboard page has none. Pass --single-page to treat the whole page as one record, optionally with --main-content to skip nav/footer/sidebar. See Single-page mode.
If the page is a listing, it's probably JavaScript-rendered — see Empty shell below.
API mode returns zero items
Almost always start_page: the blueprint says 0 but the API is 1-indexed, so the first request returns an empty list and the crawler stops. Diagnose with two curls against the first two page values; whichever has data is your start_page. The other suspect is a wrong items_path. Full walkthrough: Getting zero items? and the quotes tutorial.
API: response is not JSON
The endpoint answered with HTML (usually a challenge page or 403) instead of JSON — on cookie-protected APIs this means the anti-bot cookies expired (e.g. reese84). Re-capture the request from DevTools and refresh http_config.cookies. See Form-encoded & cookie-protected endpoints.
Blocked by <vendor>
The response was fingerprinted as a WAF block (the message names the vendor). The auto transport escalates for you — Cloudflare goes to flaresolverr, Akamai/PerimeterX-class vendors need scraping_api (paid) or a replayed browser session for one-off runs. Start at Which rung should you be on?.
Fields are null / the page is an empty shell
The content is rendered by JavaScript after load. Options, cheapest first:
- Check the Network tab for a JSON API and use API mode — no browser needed.
- Use the
browsertransport, adding--browser-wait-forwith a selector that only exists once the data has loaded (a row, not the container).
The generator usually handles this itself: it detects the empty shell, re-renders in a headless browser, and even sniffs the JSON endpoint the page calls — see Part 2 of the quotes tutorial.
The detector picked the wrong list
A sidebar or nav can be a "cleaner" repeating pattern than the real content, so the heuristics score it higher. Confirm the right item_selector in the selector shell (the match count should equal the items you see), then fix the blueprint — it's just JSON. Worked example: Part 1 of the quotes tutorial.
The infinite-scroll endpoint returns 500
Some endpoints reject parameters they don't expect — even empty ones (e.g. an empty order=). Send exactly what the real "Load more" request in the Network tab contains, no more. See Infinite scroll.
primary_image is an icon or tracking pixel
The image-quality heuristic normally down-scores icons, badges and pixels — but it can only choose among the URLs your selectors produce. Check the image field's attribute (lazy-loaded sites put the real URL in data-src, not src), and in single-page mode rely on --get-primary-image to let the heuristic pick from all page images. See Images and Single-page mode.
Where did my output go?
By default items are saved to storage/app/scrapes/<name>.json — the path is printed at the end of the run, on stderr (stdout is kept clean for piping). --output=PATH chooses the destination, --output=- prints to stdout. Crawl progress and the stats summary are stderr too. See Where output goes.
Still stuck? Open an issue at github.com/data-helm/crawler with the command, the blueprint, and the stderr output.

