{"record":{"id":"4b504552ed2cba66","repo":"apify/crawlee","slug":"configuration-is-immutable-pass-options-via-the-c","errorCode":null,"errorMessage":"Configuration is immutable. Pass options via the constructor instead.","messagePattern":"Configuration is immutable\\. Pass options via the constructor instead\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/configuration.ts","lineNumber":267,"sourceCode":"            const parsed = fieldDef.schema.safeParse(undefined);\n            values[key] = parsed.success ? parsed.data : undefined;\n        }\n\n        return values;\n    }\n\n    /**\n     * Registers getters (and throwing setters) on the instance for each field.\n     */\n    private registerAccessors(): void {\n        const fields = (this.constructor as typeof Configuration).fields;\n        const descriptors: PropertyDescriptorMap = {};\n\n        for (const key of Object.keys(fields)) {\n            descriptors[key] = {\n                get: () => this.#resolvedValues[key],\n                set() {\n                    throw new TypeError('Configuration is immutable. Pass options via the constructor instead.');\n                },\n                enumerable: true,\n                configurable: false,\n            };\n        }\n\n        Object.defineProperties(this, descriptors);\n    }\n\n    /**\n     * Reads the first defined env var value for a field definition.\n     * Empty strings are treated as unset, falling through to crawlee.json or schema defaults.\n     * (Crawlee v3 coerced `''` to `false`/`0`/`''` per type — v4 drops that for consistency.)\n     */\n    private static readEnvVar(fieldDef: ConfigField): string | undefined {\n        if (!fieldDef.envVar) return undefined;\n        const envVars = Array.isArray(fieldDef.envVar) ? fieldDef.envVar : [fieldDef.envVar];\n        for (const envVar of envVars) {","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/core/src/configuration.ts#L249-L285","documentation":"Crawlee Configuration instances are frozen: resolved option fields get setters that throw a TypeError. Options must be provided when the Configuration is constructed; mutating a global or existing instance afterwards is deliberately unsupported.","triggerScenarios":"Assigning to a configuration field at runtime, e.g. `Configuration.getGlobal().persistStorage = false` or `config.defaultDatasetId = 'x'`, after the instance was created.","commonSituations":"Toggling settings mid-run (persistStorage, proxies) in tests; mutating `Configuration.getGlobal()` imported from another module; code written against older Crawlee versions where the config was mutable.","solutions":["Pass all options to the constructor: `new Configuration({ persistStorage: false, ... })`.","Replace the global instance early with `Configuration.getGlobalConfig()` / set a fresh `new Configuration(...)` before any storage clients initialize.","Restructure code so options are known before the run starts instead of mutating later."],"exampleFix":"// before\nconst config = Configuration.getGlobal();\nconfig.persistStorage = false;\n// after\nconst config = new Configuration({ persistStorage: false });","handlingStrategy":"validation","validationCode":"// configure once, at startup, before anything reads the config\nconst config = new Configuration({ persistStorage: false, defaultDatasetId: 'my-dataset' });","typeGuard":"function isMutableConfigWrite(key: string): boolean { return ['persistStorage','defaultDatasetId','memoryMbytes'].includes(key); } // treat all resolved fields as read-only instead","tryCatchPattern":"try { (config as any).persistStorage = false; } catch (err) { if (err instanceof TypeError && err.message.includes('immutable')) { config = new Configuration({ persistStorage: false }); } else { throw err; } }","preventionTips":["Never mutate Configuration instances; construct a new one with all options","Set global configuration at process start before storage clients initialize","Update code written against older, mutable Crawlee Configuration APIs"],"tags":["configuration","immutability","core","typescript"],"backgroundTag":"immutable-object-mutation","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}