apify/crawlee · error · Error
The `minConcurrency`/`maxConcurrency`/`initialConcurrency`/`
Error message
The `minConcurrency`/`maxConcurrency`/`initialConcurrency`/`maxRequestsPerMinute` shortcuts cannot be combined with `concurrencySystem` - they configure the default `ConcurrencySystem` that a supplied one replaces. Pass them to the `ConcurrencySystem` constructor instead.
What it means
BasicCrawler accepts either a custom `concurrencySystem` or the legacy convenience shortcuts (`minConcurrency`, `maxConcurrency`, `initialConcurrency`, `maxRequestsPerMinute`) that configure the built-in default ConcurrencySystem. Passing both is contradictory because the shortcuts would configure a system the custom one replaces, so the constructor rejects it at startup.
Source
Thrown at packages/basic-crawler/src/internals/basic-crawler.ts:1039
statusMessageLoggingInterval,
statusMessageCallback,
statistics,
httpClient,
id,
} = parsedOptions;
// All concurrency configuration lives on the `ConcurrencySystem`, so the shortcuts have nowhere to go once
// one is supplied - and silently dropping a `maxConcurrency` the user asked for is how crawls end up
// hammering a site.
if (
concurrencySystem !== undefined &&
(minConcurrency !== undefined ||
maxConcurrency !== undefined ||
initialConcurrency !== undefined ||
maxRequestsPerMinute !== undefined)
) {
throw new Error(
'The `minConcurrency`/`maxConcurrency`/`initialConcurrency`/`maxRequestsPerMinute` shortcuts ' +
'cannot be combined with `concurrencySystem` - they configure the default `ConcurrencySystem` ' +
'that a supplied one replaces. Pass them to the `ConcurrencySystem` constructor instead.',
);
}
// Create per-crawler service locator if custom services were provided.
// This wraps every method on the crawler instance so that calls to the global `serviceLocator`
// (via AsyncLocalStorage) resolve to this scoped instance instead.
// We also enter the scope for the rest of the constructor body, so that any code below
// that accesses `serviceLocator` will see the correct (scoped) instance.
let serviceLocatorScope = { enterScope: () => {}, exitScope: () => {} };
if (
storageBackend ||
eventManager ||
logger ||
(configuration !== undefined && configuration !== serviceLocator.getConfiguration())View on GitHub (pinned to dbe57fb09c)
Solutions
- Remove the shortcut options from the BasicCrawler options object.
- Pass minConcurrency/maxConcurrency/initialConcurrency/maxRequestsPerMinute to the ConcurrencySystem constructor and supply that system via `concurrencySystem`.
Example fix
// before
const crawler = new BasicCrawler({
concurrencySystem: new ConcurrencySystem(),
maxRequestsPerMinute: 120,
});
// after
const crawler = new BasicCrawler({
concurrencySystem: new ConcurrencySystem({ maxRequestsPerMinute: 120 }),
}); Defensive patterns
Strategy: validation
Validate before calling
const shortcuts = ['minConcurrency', 'maxConcurrency', 'initialConcurrency', 'maxRequestsPerMinute'];
if (opts.concurrencySystem && shortcuts.some((k) => opts[k] !== undefined)) {
throw new Error('Use either concurrencySystem or the concurrency shortcuts, not both.');
} Prevention
- Pick one concurrency configuration style per project and stick to it.
- When introducing a custom ConcurrencySystem, move all tuning options into its constructor in the same commit.
- Keep crawler option objects typed so excess/incompatible keys fail type checks.
When it happens
Trigger: Calling `new BasicCrawler({ concurrencySystem: mySystem, maxConcurrency: 5 })` (or with any of minConcurrency/initialConcurrency/maxRequestsPerMinute) while also supplying a concurrencySystem.
Common situations: Migrating from shortcut options to a custom ConcurrencySystem and leaving old tuning options in the config object; copying example code that mixes both styles.
Related errors
- The `requestManager` option cannot be used in conjunction wi
- This crawler instance is already running, you can add more r
- Cannot decide what to purge before running again: `sameDomai
- Failed to infer format from the path: '${path}'. Supported f
- Unsupported format: '${format}'. Use one of ${supportedForma
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/752827df9bb113b1.
Report an issue: GitHub.