apify/crawlee · error · Error
The custom statistics field `${String(key)}` collides with a
Error message
The custom statistics field `${String(key)}` collides with a built-in one - it would shadow the value the crawler tracks. Rename it in `stateExtension`. What it means
Statistics supports custom tracked fields via a stateExtension. This error is thrown in the Statistics constructor when a custom field name matches one of the built-in statistics fields, because it would shadow values the crawler tracks internally. Rename the custom field to avoid the collision.
Source
Thrown at packages/core/src/crawlers/statistics.ts:361
this.id = id ?? String(Statistics.#id++);
this.#persistStateKey = `CRAWLEE_CRAWLER_STATISTICS_${this.id}`;
this.log = (log ?? serviceLocator.getLogger()).child({ prefix: 'Statistics' });
this.errorTracker = new ErrorTracker({ ...errorTrackerConfig, saveErrorSnapshots });
this.errorTrackerRetry = new ErrorTracker({ ...errorTrackerConfig, saveErrorSnapshots });
this.#logIntervalMillis = logIntervalSecs * 1000;
this.#logMessage = logMessage;
this.#stateExtension = stateExtension as StatisticStateExtensionOptions<
StateExtension,
PersistedStateExtension
>;
this.#defaultStateExtension = this.#resolveDefaultStateExtension(this.#stateExtension);
this.#stateExtensionKeys = Object.keys(this.#defaultStateExtension()) as (keyof StateExtension)[];
for (const key of this.#stateExtensionKeys) {
if ((key as string) in this.#builtInDefaultState()) {
throw new Error(
`The custom statistics field \`${String(key)}\` collides with a built-in one - it would shadow ` +
'the value the crawler tracks. Rename it in `stateExtension`.',
);
}
}
// `calculate()` is late-bound on purpose - it is an override point, and a subclass's must be the one that runs.
this.#stateCodec = buildStatisticStateCodec({
statsId: this.id,
defaultState: () => this.#defaultState(),
calculate: () => this.calculate(),
});
this.#recoverableState = new RecoverableState({
persistStateKey: this.#persistStateKey,
persistenceEnabled: persistenceOptions.enable,
keyValueStore,
logger: this.log,View on GitHub (pinned to dbe57fb09c)
Solutions
- Rename the colliding key in stateExtension (deserialize/defaultState)
- Log Object.keys(built-in default state) to compare against your custom keys
- Pick a prefixed naming convention for custom fields (e.g. `custom_` prefix)
- After library upgrades, re-check for collisions with newly added built-in fields
Example fix
// before
stateExtension: { deserialize: (s) => ({ errors: s.e }) }
// after
stateExtension: { deserialize: (s) => ({ customErrors: s.e }) } Defensive patterns
Strategy: validation
Validate before calling
const builtIn = Object.keys(crawler.stats.state); // inspect before naming custom fields
const clash = Object.keys(myDefaults).filter((k) => builtIn.includes(k));
if (clash.length) throw new Error(`rename custom fields: ${clash}`); Try / catch
try { new Statistics({ stateExtension }); } catch (e) { if (String(e).includes('collides with a built-in')) renameFields(); else throw e; } Prevention
- Prefix custom stat fields (e.g. custom_)
- Re-check names after upgrading the library
- Diff custom keys against built-in default state in tests
When it happens
Trigger: Passing a stateExtension whose deserialized/default state contains a key present in the built-in default state (e.g. `errors`, `requestsFinished`, `crawlerStartedAt`).
Common situations: Extending crawler stats with common field names after migrating code; copying built-in field names into custom extensions; merging two configs where a custom field collides with newer built-ins after a library upgrade.
Related errors
- Could not derive the default values of the custom statistics
- The `minConcurrency`/`maxConcurrency`/`initialConcurrency`/`
- The `requestManager` option cannot be used in conjunction wi
- Cannot decide what to purge before running again: `sameDomai
- Failed to infer format from the path: '${path}'. Supported f
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/ac2ccf3ca9f2887f.
Report an issue: GitHub.