{"record":{"id":"f9291cbb09fa5390","repo":"apify/crawlee","slug":"cannot-persist-state-options-persiststatekey-is-n","errorCode":null,"errorMessage":"Cannot persist state. options.persistStateKey is not set.","messagePattern":"Cannot persist state\\. options\\.persistStateKey is not set\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/storages/request_list.ts","lineNumber":458,"sourceCode":"                    // oxlint-disable-next-line typescript/no-array-delete -- intentional, drop the slot so V8 can collect the object\n                    delete sourcesFromFunction[i];\n                    this.addRequest(source);\n                }\n\n                sourcesFromFunction.length = 0;\n            } catch (e) {\n                const err = e as Error;\n                throw new Error(`Loading requests with sourcesFunction failed.\\nCause: ${err.message}`);\n            }\n        }\n    }\n\n    /**\n     * @inheritDoc\n     */\n    async persistState(): Promise<void> {\n        if (!this.#persistStateKey) {\n            throw new Error('Cannot persist state. options.persistStateKey is not set.');\n        }\n        if (this.isStatePersisted) return;\n        try {\n            this.#store ??= await KeyValueStore.open();\n            await this.#store.setValue(this.#persistStateKey, this.getState());\n            this.isStatePersisted = true;\n        } catch (e) {\n            const err = e as Error;\n            this.#log.exception(err, 'Attempted to persist state, but failed.');\n        }\n    }\n\n    /**\n     * Removes the `PERSIST_STATE` event listener registered during initialization and persists\n     * the current state one last time. Call this when you are done with the `RequestList` to avoid\n     * leaking the listener (and the requests it retains) on the shared event manager.\n     */\n    async teardown(): Promise<void> {","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/core/src/storages/request_list.ts#L440-L476","documentation":"persistState() saves the list's processed-position state to the default KeyValueStore, but only when a persistStateKey was configured at construction. Without the key there is nowhere to persist, so the method throws instead of silently doing nothing.","triggerScenarios":"Calling list.persistState() (directly or via crawler.teardown / persistence hooks) on a RequestList constructed without a persistStateKey option.","commonSituations":"Adding periodic persistence to an existing list and forgetting the constructor option; calling crawlerTeardown/persist hooks generically for all storages while one list lacks the key.","solutions":["Pass persistStateKey when creating the list: new RequestList({ sources, persistStateKey: 'my-state' })","Or guard the call: only invoke persistState() when list has a configured key","If state persistence is unwanted, remove the persistState() call rather than catching the error"],"exampleFix":"// before\nconst list = await RequestList.open('list', { sources });\nawait list.persistState(); // throws\n// after\nconst list = await RequestList.open('list', { sources, persistStateKey: 'list-state', persistRequestsKey: 'list-reqs' });\nawait list.persistState();","handlingStrategy":"try-catch","validationCode":"if (!list.persistStateKey && typeof list.persistState === 'function') {\n  // configure the key at construction instead of calling persistState\n}","typeGuard":null,"tryCatchPattern":"try {\n  await list.persistState();\n} catch (e) {\n  if (e.message.includes('persistStateKey is not set')) {\n    console.warn('State persistence skipped: no persistStateKey configured');\n  } else throw e;\n}","preventionTips":["Always pass persistStateKey (and persistRequestsKey) when you intend to persist","Only call persistState on lists constructed with a key","Centralize list creation so the key is not forgotten"],"tags":["request-list","persistence","configuration"],"backgroundTag":"missing-required-option","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}