{"id":"129a423c20c238d3","repo":"vitejs/vite","slug":"not-implemented-property-prop","errorCode":null,"errorMessage":"Not implemented property: ${prop}","messagePattern":"Not implemented property: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/optimizer/pluginConverter.ts","lineNumber":149,"sourceCode":"      }\n\n      for (const cb of onStartCallbacks) {\n        cb()\n      }\n    },\n    generateBundle(_outputOpts, _bundle, isWrite) {\n      const buildResult = new Proxy(\n        {\n          metafile: undefined,\n          mangleCache: undefined,\n          ...(isWrite ? { outputFiles: undefined } : {}),\n        } as esbuild.BuildResult,\n        {\n          get(_target, prop) {\n            if (prop in _target || typeof prop === 'symbol') {\n              return (_target as any)[prop]\n            }\n            throw new Error('Not implemented property: ' + prop)\n          },\n        },\n      )\n      for (const cb of onEndCallbacks) {\n        cb(buildResult)\n      }\n    },\n    async resolveId(id, importer, opts) {\n      for (const handler of resolveIdHandlers) {\n        const result = await handler.call(this, id, importer, opts)\n        if (result) {\n          if (typeof result === 'object' && result.namespace) {\n            usedNamespaces.add(result.namespace)\n          }\n          return result\n        }\n      }\n      if (usedNamespaces.size) {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/optimizer/pluginConverter.ts#L131-L167","documentation":"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.","triggerScenarios":"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.","commonSituations":"Plugins that report build stats, write metafile analysis, or inspect outputs in `onEnd`; plugins written against a fuller esbuild BuildResult.","solutions":["Only read `metafile`, `mangleCache`, and (write-mode) `outputFiles` from the onEnd result — and expect them to be `undefined`.","Move post-build analysis to a rolldown `generateBundle`/`writeBundle` hook where the real bundle is available.","Remove the plugin from `optimizeDeps.esbuildOptions.plugins`."],"exampleFix":"// before\nonEnd((result) => { for (const k of Object.keys(result.metafile.outputs)) ... })\n\n// after — skip metafile analysis in the esbuild-shimmed plugin","handlingStrategy":"validation","validationCode":"const SUPPORTED_RESULT = new Set(['metafile', 'mangleCache', 'outputFiles'])\nfunction assertOnEndResultAccess(plugin: any) {\n  const m = plugin.setup.toString().match(/onEnd\\(([\\s\\S]+?)\\)\\s*=>?\\s*\\{([\\s\\S]*?)\\}\\)/)\n  if (m) {\n    const used = [...m[2].matchAll(/\\bresult\\.(\\w+)/g)].map((x) => x[1])\n    const bad = used.filter((k) => !SUPPORTED_RESULT.has(k))\n    if (bad.length) throw new Error(`onEnd reads unsupported BuildResult keys: ${bad.join(', ')}`)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only read metafile/mangleCache/outputFiles from onEnd result in optimizer esbuild plugins.","Do post-build analysis in a rolldown generateBundle hook."],"tags":["optimizer","plugin","esbuild","rolldown","interop"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}