{"id":"bc347594e4ad67ad","repo":"vitest-dev/vitest","slug":"environment-name-is-not-a-valid-environment","errorCode":null,"errorMessage":"Environment \"${name}\" is not a valid environment. Path \"${packageId}\" should export default object with a \"setup\" or/and \"setupVM\" method.","messagePattern":"Environment \"(.+?)\" is not a valid environment\\. Path \"(.+?)\" should export default object with a \"setup\" or/and \"setupVM\" method\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/integrations/env/loader.ts","lineNumber":74,"sourceCode":"\nexport async function loadNativeEnvironment(\n  name: string,\n  root: string,\n  traces: Traces,\n): Promise<Environment> {\n  const packageId = name[0] === '.' || name[0] === '/'\n    ? pathToFileURL(resolve(root, name)).toString()\n    : import.meta.resolve(`vitest-environment-${name}`, pathToFileURL(root).toString())\n  const pkg = await traces.$(\n    'vitest.runtime.environment.import',\n    () => import(packageId) as Promise<{ default: Environment }>,\n  )\n  return resolveEnvironmentFromModule(name, packageId, pkg)\n}\n\nfunction resolveEnvironmentFromModule(name: string, packageId: string, pkg: { default: Environment }) {\n  if (!pkg || !pkg.default || typeof pkg.default !== 'object') {\n    throw new TypeError(\n      `Environment \"${name}\" is not a valid environment. `\n      + `Path \"${packageId}\" should export default object with a \"setup\" or/and \"setupVM\" method.`,\n    )\n  }\n  const environment = pkg.default\n  if (\n    environment.transformMode != null\n    && environment.transformMode !== 'web'\n    && environment.transformMode !== 'ssr'\n  ) {\n    throw new TypeError(\n      `Environment \"${name}\" is not a valid environment. `\n      + `Path \"${packageId}\" should export default object with a \"transformMode\" method equal to \"ssr\" or \"web\", received \"${environment.transformMode}\".`,\n    )\n  }\n  if (environment.transformMode) {\n    console.warn(`The Vitest environment ${environment.name} defines the \"transformMode\". This options was deprecated in Vitest 4 and will be removed in the next major version. Please, use \"viteEnvironment\" instead.`)\n    // keep for backwards compat","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/integrations/env/loader.ts#L56-L92","documentation":"When loading a custom environment (`vitest-environment-<name>` or a path), Vitest imports the module and requires a default export that is an object exposing `setup` and/or `setupVM`. If the default export is missing, not an object, or lacks those methods, the loader rejects it as invalid so the environment contract is enforced up front rather than failing cryptically during test setup.","triggerScenarios":"Setting `environment: 'myenv'` (resolving to `vitest-environment-myenv`) or `environment: './env.js'` where the module exports no default, exports a function/class as default, or exports a default object without `setup`/`setupVM`.","commonSituations":"Authoring a custom environment and forgetting the default export; naming the methods incorrectly (e.g. `init` instead of `setup`); CJS module whose `module.exports = ...` is not shaped as a default object; pointing `environment` at a path that re-exports incorrectly.","solutions":["Ensure the environment module has `export default { name, setup(opts) { ... return { teardown() {} } } }` (and/or `setupVM`).","If using CommonJS, use `module.exports = { setup, setupVM }` so Vitest sees it as the default object.","Verify the resolved path actually points to your environment file (check the error's `packageId`)."],"exampleFix":"// before\nexport function setup() { return { teardown() {} } }\n// after\nexport default {\n  name: 'myenv',\n  setup({ provide }) { return { teardown() {} } },\n}","handlingStrategy":"type-guard","validationCode":"// validate your environment module before publishing\nimport * as env from './my-env.js'\nconst ok = typeof env.default === 'object' && env.default !== null\n  && (typeof env.default.setup === 'function' || typeof env.default.setupVM === 'function')","typeGuard":"import type { Environment } from 'vitest'\nfunction isEnvironment(v: unknown): v is Environment {\n  return typeof v === 'object' && v !== null\n    && (typeof (v as any).setup === 'function' || typeof (v as any).setupVM === 'function')\n}","tryCatchPattern":null,"preventionTips":["Always `export default { name, setup, setupVM }` from custom environments.","Use the `Environment` type from `vitest` to get compile-time shape checks."],"tags":["environment","config","custom-environment","loader"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}