{"id":"5ee2c85aa9f478f2","repo":"vitejs/vite","slug":"this-name-environment-plugincontainer-called-be","errorCode":null,"errorMessage":"${this.name} environment.pluginContainer called before initialized","messagePattern":"(.+?) environment\\.pluginContainer called before initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/optimizer/scan.ts","lineNumber":50,"sourceCode":"  virtualModuleRE,\n} from '../utils'\nimport type { EnvironmentPluginContainer } from '../server/pluginContainer'\nimport {\n  ERR_CLOSED_SERVER,\n  createEnvironmentPluginContainer,\n} from '../server/pluginContainer'\nimport { BaseEnvironment } from '../baseEnvironment'\nimport type { DevEnvironment } from '../server/environment'\nimport { transformGlobImport } from '../plugins/importMetaGlob'\nimport { cleanUrl } from '../../shared/utils'\nimport { getRollupJsxPresets } from '../plugins/oxc'\n\nexport class ScanEnvironment extends BaseEnvironment {\n  mode = 'scan' as const\n\n  get pluginContainer(): EnvironmentPluginContainer {\n    if (!this._pluginContainer)\n      throw new Error(\n        `${this.name} environment.pluginContainer called before initialized`,\n      )\n    return this._pluginContainer\n  }\n  /**\n   * @internal\n   */\n  _pluginContainer: EnvironmentPluginContainer | undefined\n\n  async init(): Promise<void> {\n    if (this._initiated) {\n      return\n    }\n    this._initiated = true\n    this._pluginContainer = await createEnvironmentPluginContainer(\n      this,\n      this.plugins,\n      undefined,","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/optimizer/scan.ts#L32-L68","documentation":"`ScanEnvironment.pluginContainer` is a lazy getter that throws until `init()` has populated `_pluginContainer`. The scan environment is a restricted view used during dependency scanning, and accessing its plugin container before initialization (scan.ts:50) indicates an ordering bug — the container isn't built until `ScanEnvironment.init()` runs.","triggerScenarios":"Calling `environment.pluginContainer` on a `ScanEnvironment` (or a `devToScanEnvironment` wrapper) before awaiting its `init()`. Typically an internal Vite path or a custom Environment API consumer touching the container too early.","commonSituations":"Custom environments using the experimental Environment API that access `pluginContainer` in a constructor/before-init hook; framework integrations racing plugin setup against scan init; Vite internal regression around scan ordering.","solutions":["Always `await environment.init()` before reading `environment.pluginContainer`.","If you built a custom ScanEnvironment, ensure `_pluginContainer` is assigned in `init()` exactly as the base class does.","Reorder your setup so plugin-container access happens after the environment is initialized.","Report as a Vite internal bug if you're not constructing the environment yourself."],"exampleFix":"// before\nconst env = new ScanEnvironment(...)\nconst container = env.pluginContainer // throws\n\n// after\nconst env = new ScanEnvironment(...)\nawait env.init()\nconst container = env.pluginContainer","handlingStrategy":"validation","validationCode":"function assertScanInitialized(env: ScanEnvironment) {\n  if (!('_pluginContainer' in env) || (env as any)._pluginContainer == null)\n    throw new Error('Call await environment.init() before accessing pluginContainer')\n}","typeGuard":"function isScanReady(env: ScanEnvironment): boolean {\n  return (env as any)._pluginContainer != null\n}","tryCatchPattern":null,"preventionTips":["Always await environment.init() before touching pluginContainer on a ScanEnvironment.","Treat pluginContainer as lazy/async-initialized; never read it in constructors."],"tags":["optimizer","scan","environment-api","initialization","internal"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}