vitest-dev/vitest · error · Error
No property descriptor for ${globalName}, this is a bug in V
Error message
No property descriptor for ${globalName}, this is a bug in Vitest. What it means
populateNodeGlobals iterates Object.getOwnPropertyNames(globalThis) and immediately calls Object.getOwnPropertyDescriptor for each name. The error fires if getOwnPropertyDescriptor returns undefined for a name that getOwnPropertyNames just returned — a logical impossibility in a single-threaded, stable runtime. The message explicitly says 'this is a bug in Vitest,' signaling an internal invariant violation, likely caused by concurrent modification of globalThis during enumeration.
Source
Thrown at packages/vitest/src/integrations/env/node.ts:32
const nodeGlobals = new Map<string, PropertyDescriptor>()
function populateNodeGlobals() {
if (nodeGlobals.size !== 0) {
return
}
const names = Object.getOwnPropertyNames(globalThis)
const length = names.length
for (let i = 0; i < length; i++) {
const globalName = names[i]
if (!denyList.has(globalName)) {
const descriptor = Object.getOwnPropertyDescriptor(
globalThis,
globalName,
)
if (!descriptor) {
throw new Error(
`No property descriptor for ${globalName}, this is a bug in Vitest.`,
)
}
nodeGlobals.set(globalName, descriptor)
}
}
}
export default <Environment>{
name: 'node',
viteEnvironment: 'ssr',
// this is largely copied from jest's node environment
async setupVM() {
populateNodeGlobals()
const vm = await import('node:vm')
let context = vm.createContext()
let global = vm.runInContext('this', context)View on GitHub (pinned to 1fa9837ec2)
Solutions
- Identify any code that mutates globalThis during test setup and defer it until after environment initialization.
- Update Vitest — newer versions may handle concurrent global mutation more defensively.
- If reproducible, file a Vitest bug with the globalThis property name and the mutating library identified.
Defensive patterns
Strategy: try-catch
Try / catch
try {
// run tests that trigger node environment setup
} catch (e) {
if (e.message.includes('No property descriptor') && e.message.includes('bug in Vitest')) {
// report to Vitest; identify globalThis mutator
} else throw e
} Prevention
- Avoid libraries that delete/redefine globalThis properties during module load.
- Load globalThis-mutating polyfills before the test framework initializes.
When it happens
Trigger: Another library or a previously-loaded test mutates globalThis (deletes or redefines properties) while populateNodeGlobals is enumerating, so a name returned by getOwnPropertyNames no longer has a descriptor by the time getOwnPropertyDescriptor is called. Also theoretically triggerable by a custom Node build or VM context with non-standard global semantics.
Common situations: Extremely rare. Seen in environments where globalThis is being proxied or heavily mutated (e.g. some sandboxing libraries, polyfills that delete/redefine globals during load). Almost always an environment bug, not a user config issue.
Related errors
- vitest/browser can be imported only inside the Browser Mode.
- received value must a Node or a Locator that returns a Node.
- Not called in the browser
- Browser provider is not defined for the project "${child.pro
- Cannot spawn child server without a parent dev server.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/56bc196473b7a600.
Report an issue: GitHub.