{"id":"5ecd59e0e5d73dca","repo":"vitejs/vite","slug":"required-environments-configuration-were-stripped","errorCode":null,"errorMessage":"Required environments configuration were stripped out in the config hook","messagePattern":"Required environments configuration were stripped out in the config hook","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/vite/src/node/config.ts","lineNumber":1664,"sourceCode":"          external: config.ssr?.external,\n          noExternal: config.ssr?.noExternal,\n        },\n      } satisfies EnvironmentOptions,\n      {\n        resolve: configEnvironmentsSsr.resolve ?? {},\n      },\n    ).resolve\n  }\n\n  if (config.build?.ssrEmitAssets !== undefined) {\n    configEnvironmentsSsr ??= {}\n    configEnvironmentsSsr.build ??= {}\n    configEnvironmentsSsr.build.emitAssets = config.build.ssrEmitAssets\n  }\n\n  // The client and ssr environment configs can't be removed by the user in the config hook\n  if (!config.environments.client || (!config.environments.ssr && !isBuild)) {\n    throw new Error(\n      'Required environments configuration were stripped out in the config hook',\n    )\n  }\n\n  // Merge default environment config values\n  const defaultEnvironmentOptions = getDefaultEnvironmentOptions(config)\n  // Some top level options only apply to the client environment\n  const defaultClientEnvironmentOptions: UserConfig = {\n    ...defaultEnvironmentOptions,\n    input: config.input,\n    resolve: config.resolve, // inherit everything including mainFields and conditions\n    optimizeDeps: config.optimizeDeps,\n  }\n  const defaultNonClientEnvironmentOptions: UserConfig = {\n    ...defaultEnvironmentOptions,\n    dev: {\n      ...defaultEnvironmentOptions.dev,\n      createEnvironment: undefined,","sourceCodeStart":1646,"sourceCodeEnd":1682,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/config.ts#L1646-L1682","documentation":"In resolveConfig (config.ts:1663-1667), Vite asserts that the client environment (and the ssr environment when not building) still exist after config hooks run. These default environments are required and cannot be removed by user config or plugins; if a config hook stripped them, Vite throws.","triggerScenarios":"A plugin's config() hook (or a returned config merge) that deletes or overrides environments such that environments.client (or environments.ssr in dev) is missing.","commonSituations":"A plugin that returns { environments: { ... } } omitting client/ssr; merging configs that replace rather than extend environments; experimental environment manipulation gone wrong.","solutions":["Make config hooks extend environments rather than replace — always keep environments.client (and ssr for serve).","Return only the new/changed environment keys from the config hook so Vite merges them.","If you must reshape environments, re-add client and ssr explicitly."],"exampleFix":"// before (plugin config hook)\nconfig() { return { environments: { custom: { ... } } } } // dropped client/ssr\n// after\nconfig() { return { environments: { custom: { ... } } } } // but ensure resolveConfig still sees client/ssr — i.e., don't overwrite the whole map; merge instead","handlingStrategy":"validation","validationCode":"const resolved = await resolveConfig(config, 'serve')\nif (!resolved.environments.client || (!resolved.environments.ssr && !isBuild)) {\n  throw new Error('Required environments were stripped — fix config hooks')\n}","typeGuard":"function hasRequiredEnvironments(config: ResolvedConfig, isBuild: boolean): boolean {\n  return Boolean(config.environments.client) &&\n    (isBuild || Boolean(config.environments.ssr))\n}","tryCatchPattern":null,"preventionTips":["In plugin config hooks, merge into environments rather than replacing the map.","Never delete environments.client or environments.ssr.","Add a test that resolves config and asserts the default environments survive."],"tags":["config","environment","plugin","validation"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}