vitest-dev/vitest · error · Error

No property descriptor for

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.

Solutions

  1. Identify any code that mutates globalThis during test setup and defer it until after environment initialization.
  2. Update Vitest — newer versions may handle concurrent global mutation more defensively.
  3. 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

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


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/56bc196473b7a600. Report an issue: GitHub.

Appendix: 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)