From f1dab72f2a721a2981547792fb106fe6f315295f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hanu=C5=A1?= Date: Sun, 5 Jul 2026 01:03:32 +0200 Subject: [PATCH] docs(crawlee): warn against `router:` as top-level CheerioCrawler option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewing AI-generated Crawlee code, one recurring mistake is passing the router under a `router` option (or in addition to `requestHandler`): new CheerioCrawler({ router, requestHandler: async (ctx) => { ... } }) Crawlee has no top-level `router` option. At runtime this fails ow validation with `ArgumentError: Did not expect property 'router' to exist ... at new HttpCrawler`. In TypeScript projects it fails at compile time with `TS2353: 'router' does not exist in type 'CheerioCrawlerOptions'`. The scraping-basics-legacy "Initialization and setting up" lesson already shows the correct pattern (`requestHandler: router`) — this commit adds a short caution admonition right below that snippet that spells out the anti-pattern, quotes both error messages verbatim, and calls out that this is a common suggestion from AI chat tools and agentic coding assistants. No code paths or examples change; the addition is a single admonition block. Surfaced during an evaluation of Apify surfaces for agent-driven Actor development. Co-Authored-By: Claude Opus 4.7 --- .../challenge/initializing_and_setting_up.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sources/academy/webscraping/scraping_basics_legacy/challenge/initializing_and_setting_up.md b/sources/academy/webscraping/scraping_basics_legacy/challenge/initializing_and_setting_up.md index 89e8eaca61..f2861a7bea 100644 --- a/sources/academy/webscraping/scraping_basics_legacy/challenge/initializing_and_setting_up.md +++ b/sources/academy/webscraping/scraping_basics_legacy/challenge/initializing_and_setting_up.md @@ -67,6 +67,37 @@ router.addDefaultHandler(({ log }) => { }); ``` +:::caution Pass the router as `requestHandler`, not as `router` + +In `main.js` above, note that the router built with `createCheerioRouter()` is passed to the crawler under the `requestHandler` option. `CheerioCrawler` (and every other Crawlee crawler) has no top-level `router` option. Setting one will fail validation at construction time: + +```text +ArgumentError: Did not expect property `router` to exist, got ... + at new HttpCrawler ... +``` + +In TypeScript projects the same mistake surfaces at compile time: + +```text +error TS2353: Object literal may only specify known properties, +and 'router' does not exist in type 'CheerioCrawlerOptions'. +``` + +Correct: + +```js +const crawler = new CheerioCrawler({ requestHandler: router }); +``` + +Incorrect (a common AI-generated pattern to watch out for when reviewing suggestions from chat tools or agentic coding assistants): + +```js +// Do NOT do this — `router` is not a valid CheerioCrawlerOptions key. +const crawler = new CheerioCrawler({ router, requestHandler: async (ctx) => {} }); +``` + +::: + Finally, we'll add the following input file to **INPUT.json** in the project's root directory (next to `package.json`, `node_modules` and others) ```json