denoland/deno · error · NodeTypeError
ERR_INVALID_OBJECT_DEFINE_PROPERTY
ERR_INVALID_OBJECT_DEFINE_PROPERTY
Error message
'process.env' does not accept an accessor(getter/setter) descriptor
What it means
The defineProperty trap of the process.env Proxy rejects accessor descriptors: any attributes object containing get or set throws ERR_INVALID_OBJECT_DEFINE_PROPERTY with the 'does not accept an accessor(getter/setter) descriptor' message. process.env is backed by real OS environment strings, so per-variable getter/setter semantics cannot be represented.
Source
Thrown at ext/node/polyfills/_process/process.ts:182
}
return typeof denoEnvGet(prop) === "string";
},
deleteProperty(target, key) {
if (typeof key === "symbol") {
delete target[key];
return true;
}
Deno.env.delete(String(key));
return true;
},
defineProperty(target, property, attributes) {
if (
ObjectHasOwn(attributes, "get") ||
ObjectHasOwn(attributes, "set")
) {
throw new ERR_INVALID_OBJECT_DEFINE_PROPERTY(
"'process.env' does not accept an " +
"accessor(getter/setter) descriptor",
);
}
if (
!attributes?.configurable || !attributes?.enumerable ||
!attributes?.writable
) {
throw new ERR_INVALID_OBJECT_DEFINE_PROPERTY(
"'process.env' only accepts a " +
"configurable, writable," +
" and enumerable data descriptor",
);
}
if (typeof property === "symbol") {
ReflectDefineProperty(target, property, {View on GitHub (pinned to 89f33cbef2)
Solutions
- Use plain assignment instead: process.env.K = 'v'
- Wrap env access in your own config object if you need getters/computed values
- In tests, save the old value, assign, and restore afterwards rather than redefining
- Delete with delete process.env.K during cleanup
Example fix
// before
Object.defineProperty(process.env, 'NODE_ENV', {
get: () => 'test',
configurable: true,
}); // throws
// after
process.env.NODE_ENV = 'test'; Defensive patterns
Strategy: validation
Validate before calling
function isAccessorDescriptor(attrs) {
return !!attrs && ('get' in attrs || 'set' in attrs);
}
if (isAccessorDescriptor(desc)) {
process.env[key] = String(desc.value ?? ''); // use assignment instead
} else {
Object.defineProperty(process.env, key, desc);
} Try / catch
try {
Object.defineProperty(process.env, k, desc);
} catch (e) {
if (e.code === 'ERR_INVALID_OBJECT_DEFINE_PROPERTY') {
process.env[k] = String(desc.value);
} else throw e;
} Prevention
- Treat process.env as a plain string map, not an object to instrument
- Build a typed config layer over env instead of getters on env itself
- In tests, use save/assign/restore helpers instead of defineProperty stubs
When it happens
Trigger: Object.defineProperty(process.env, 'K', { get() {...}, set(v) {...} }); test spies/stubs that redefine env properties via defineProperty; frameworks trying to make env reads observable or reactive.
Common situations: Test tooling stubbing env vars (sinon-style); reactive-config libraries wrapping env in accessors; porting browser-style observable patterns onto process.env.
Related errors
- Cannot convert a Symbol value to a string
- Invalid URL: ${raw}
- ERR_INVALID_ARG_TYPE
- The bench name can't be empty
- Expected 'fn' field in the first argument to be a bench func
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/3a0a529053d177c6.
Report an issue: GitHub.