vitejs/vite · error · Error

`input` cannot contain glob characters. They are reserved, s

Error message

`input` cannot contain glob characters. They are reserved, so the ${JSON.stringify(value)} is not allowed. Please escape them with a backslash (\)

What it means

In unescapeGlobCharacters (config.ts:949-956), Vite rejects any input value that isDynamicPattern (contains unescaped glob characters like *, ?, [], {}, etc.). Glob characters are reserved so Vite can later enable glob inputs without a breaking change; they must be escaped with a backslash if you mean them literally.

Source

Thrown at packages/vite/src/node/config.ts:952

  if (typeof input === 'string') {
    return unescapeGlobCharacters(input)
  }
  if (Array.isArray(input)) {
    return input.map(unescapeGlobCharacters)
  }
  const resolved: Record<string, string> = {}
  for (const key in input) {
    resolved[key] = unescapeGlobCharacters(input[key])
  }
  return resolved
}

const escapedGlobCharactersRE = /\\([*?[\]{}()!+@|])/g

function unescapeGlobCharacters(value: string): string {
  if (isDynamicPattern(value)) {
    // so that it could later be changed to accept globs without a breaking change
    throw new Error(
      `\`input\` cannot contain glob characters. They are reserved, ` +
        `so the ${JSON.stringify(value)} is not allowed. Please escape them with a backslash (\\)`,
    )
  }
  // unescape glob characters
  return value.replace(escapedGlobCharactersRE, '$1')
}

export function resolveDevEnvironmentOptions(
  dev: DevEnvironmentOptions | undefined,
  environmentName: string | undefined,
  consumer: 'client' | 'server' | undefined,
  // Backward compatibility
  preTransformRequest?: boolean,
): ResolvedDevEnvironmentOptions {
  const resolved = mergeWithDefaults(
    {
      ...configDefaults.dev,

View on GitHub (pinned to 89620f09af)

Solutions

  1. Escape the glob characters with a backslash, e.g. 'src/\[id\].tsx'.
  2. Rename the file to avoid glob metacharacters if possible.
  3. List explicit entries instead of relying on a glob-like path.

Example fix

// before
build: { rollupOptions: { input: 'src/pages/[id].tsx' } }
// after
build: { rollupOptions: { input: 'src/pages/\[id\].tsx' } }
Defensive patterns

Strategy: validation

Validate before calling

import isDynamicPattern from 'tinyglobby'
function assertNoGlobInput(input: unknown) {
  const list = typeof input === 'string' ? [input] : Array.isArray(input) ? input : input ? Object.values(input as any) : []
  for (const v of list) if (isDynamicPattern(v as string)) throw new Error(`Glob chars in input: ${v}`)
}

Type guard

function isGlobFreeInput(input: unknown): boolean {
  const list = typeof input === 'string' ? [input] : Array.isArray(input) ? input : input ? Object.values(input as any) : []
  // simplistic check; Vite uses tinyglobby isDynamicPattern
  return !list.some((v: any) => /[*?\[\]{}!+@|]/.test(v) && !v.includes('\\'))
}

Prevention

When it happens

Trigger: Setting rollupOptions/rolldownOptions.input (or top-level input) to a path containing unescaped glob metacharacters, e.g. 'src/[dir]/main.ts' or 'src/app*(legacy).ts'.

Common situations: Pathnames with square brackets (Next.js-style dynamic routes like [id].tsx), literal asterisks, or accidentally pasting a glob into input.

Related errors


AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03). Data as JSON: /data/errors/04cea1d7270cd2a2.json. Report an issue: GitHub.