vitejs/vite · error · Error

Not implemented property: ${prop}

Error message

Not implemented property: ${prop}

What it means

In `generateBundle`, the converter builds a Proxy over a minimal fake `esbuild.BuildResult` (only `metafile`, `mangleCache`, and conditionally `outputFiles`). Reading any other string property throws 'Not implemented property: <prop>' at pluginConverter.ts:149, because rolldown's output shape doesn't map cleanly onto esbuild's result.

Source

Thrown at packages/vite/src/node/optimizer/pluginConverter.ts:149

      }

      for (const cb of onStartCallbacks) {
        cb()
      }
    },
    generateBundle(_outputOpts, _bundle, isWrite) {
      const buildResult = new Proxy(
        {
          metafile: undefined,
          mangleCache: undefined,
          ...(isWrite ? { outputFiles: undefined } : {}),
        } as esbuild.BuildResult,
        {
          get(_target, prop) {
            if (prop in _target || typeof prop === 'symbol') {
              return (_target as any)[prop]
            }
            throw new Error('Not implemented property: ' + prop)
          },
        },
      )
      for (const cb of onEndCallbacks) {
        cb(buildResult)
      }
    },
    async resolveId(id, importer, opts) {
      for (const handler of resolveIdHandlers) {
        const result = await handler.call(this, id, importer, opts)
        if (result) {
          if (typeof result === 'object' && result.namespace) {
            usedNamespaces.add(result.namespace)
          }
          return result
        }
      }
      if (usedNamespaces.size) {

View on GitHub (pinned to 89620f09af)

Solutions

  1. Only read `metafile`, `mangleCache`, and (write-mode) `outputFiles` from the onEnd result — and expect them to be `undefined`.
  2. Move post-build analysis to a rolldown `generateBundle`/`writeBundle` hook where the real bundle is available.
  3. Remove the plugin from `optimizeDeps.esbuildOptions.plugins`.

Example fix

// before
onEnd((result) => { for (const k of Object.keys(result.metafile.outputs)) ... })

// after — skip metafile analysis in the esbuild-shimmed plugin
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_RESULT = new Set(['metafile', 'mangleCache', 'outputFiles'])
function assertOnEndResultAccess(plugin: any) {
  const m = plugin.setup.toString().match(/onEnd\(([\s\S]+?)\)\s*=>?\s*\{([\s\S]*?)\}\)/)
  if (m) {
    const used = [...m[2].matchAll(/\bresult\.(\w+)/g)].map((x) => x[1])
    const bad = used.filter((k) => !SUPPORTED_RESULT.has(k))
    if (bad.length) throw new Error(`onEnd reads unsupported BuildResult keys: ${bad.join(', ')}`)
  }
}

Prevention

When it happens

Trigger: An esbuild plugin's `onEnd` callback reads a property off the `result` it receives (e.g. `result.warnings`, `result.errors`, `result.outputFiles`, `result.metafile.outputs`) that isn't in the shimmed set.

Common situations: Plugins that report build stats, write metafile analysis, or inspect outputs in `onEnd`; plugins written against a fuller esbuild BuildResult.

Related errors


AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03). Data as JSON: /data/errors/129a423c20c238d3.json. Report an issue: GitHub.