vitejs/vite · error · Error

Invalid environment name

Error message

Invalid environment name "${name}". Environment names must only contain alphanumeric characters and "$", "_".

What it means

When constructing an environment, the base environment constructor validates the name against `/^[\w$]+$/` (alphanumeric, underscore, dollar only). Names are used unescaped as directory names and accessed via `environments.<name>`, so characters like `-`, `.`, `/`, or spaces are rejected to keep filesystem and config access safe.

Solutions

  1. Rename the environment to use only `[A-Za-z0-9_$]` - e.g. `myEnv` or `my_env` instead of `my-env`.
  2. If the name comes from user input, sanitize it: `name.replace(/[^\w$]/g, '_')`.
  3. Use the conventional names `client` and `ssr` unless you need custom environments.

Example fix

// before
environments: { 'ssr-server': { ... } }
// after
environments: { ssrServer: { ... } }
Defensive patterns

Strategy: validation

Validate before calling

function assertValidEnvironmentName(name: string) {
  if (!/^[\w$]+$/.test(name)) {
    throw new Error(`Invalid environment name "${name}". Use only [A-Za-z0-9_$].`)
  }
}

Type guard

function isValidEnvironmentName(name: string): boolean {
  return /^[\w$]+$/.test(name)
}

Prevention

When it happens

Trigger: Creating an environment with a name containing a dash, dot, slash, space, or any non-word character - e.g. defining `environments: { 'my-env': {...} }` or calling `createEnvironment('ssr.client', ...)`.

Common situations: Naming environments with kebab-case (`my-env`) instead of camelCase/underscore. Deriving environment names from URLs or file paths. Copying env var names (often dashed) as environment keys.

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/0528177ad68fdb7c. Report an issue: GitHub.

Appendix: source

Thrown at packages/vite/src/node/baseEnvironment.ts:40

  /**
   * @internal
   */
  _options: ResolvedEnvironmentOptions
  /**
   * @internal
   */
  _topLevelConfig: ResolvedConfig

  constructor(
    name: string,
    topLevelConfig: ResolvedConfig,
    options: ResolvedEnvironmentOptions = topLevelConfig.environments[name],
  ) {
    // only allow some characters so that we can use name without escaping for directory names
    // and make users easier to access with `environments.*`
    if (!/^[\w$]+$/.test(name)) {
      throw new Error(
        `Invalid environment name "${name}". Environment names must only contain alphanumeric characters and "$", "_".`,
      )
    }
    this.name = name
    this._topLevelConfig = topLevelConfig
    this._options = options
    this.config = new Proxy(
      options as ResolvedConfig & ResolvedEnvironmentOptions,
      {
        get: (target, prop: keyof ResolvedConfig) => {
          if (prop === 'logger') {
            return this.logger
          }
          if (prop in target) {
            return this._options[prop as keyof ResolvedEnvironmentOptions]
          }
          return this._topLevelConfig[prop]
        },

View on GitHub (pinned to b4d66fee14)