cypress-io/cypress · error · Error

ESM plugin config value '${name}' must be an array of string

Error message

ESM plugin config value '${name}' must be an array of strings

What it means

Thrown by assertIsArrayOrUndefined in @cypress/vite-plugin-cypress-esm when validating the plugin options ignoreList, ignoreModuleList, and ignoreImportList. Each must be either undefined or an array containing only strings. Any other shape (object, number, single string, or an array with non-string elements) is rejected because the plugin feeds these arrays into picomatch matchers that require string inputs.

Source

Thrown at npm/vite-plugin-cypress-esm/src/index.ts:46

   * Module A imports Module B
   * Adding `A` to `ignoreModuleList` will prevent usages of `B` within `A` from being stubbed
   */
  ignoreModuleList?: string[]
  /**
   * Array of picomatch patterns of imports to ignore (use unaltered module). Any ignored
   * imports will not support stub/spy. Use this to remedy usages of a proxied module that cause
   * problems.
   *
   * Example:
   * Module A imports Module B
   * Adding `B` to `ignoreImportList` will prevent usages of `B` within `A` from being stubbed
   */
  ignoreImportList?: string[]
}

const assertIsArrayOrUndefined = (name: string, value: any): void => {
  if (value && (!Array.isArray(value) || value.some((val) => typeof val !== 'string'))) {
    throw new Error(`ESM plugin config value '${name}' must be an array of strings`)
  }
}

export const CypressEsm = (options?: CypressEsmOptions): Plugin => {
  // Validate config
  assertIsArrayOrUndefined('ignoreList', options?.ignoreList)
  assertIsArrayOrUndefined('ignoreModuleList', options?.ignoreModuleList)
  assertIsArrayOrUndefined('ignoreImportList', options?.ignoreImportList)

  const ignoreModuleList = ([] as string[]).concat(options?.ignoreModuleList ?? []).concat(options?.ignoreList ?? [])
  const ignoreImportList = options?.ignoreImportList ?? []
  const ignoreModuleMatcher = picomatch(ignoreModuleList)
  const ignoreImportMatcher = picomatch(ignoreImportList)

  /**
   * If a module ID is explicitly ignored then do not proxify it
   *
   * @param moduleId

View on GitHub (pinned to 0d85fdc912)

Solutions

  1. Wrap single values in an array: `ignoreModuleList: ['lodash']` instead of `'lodash'`.
  2. Ensure every element is a string; coerce or remove numbers/objects.
  3. If you want to disable a list, omit the option or set it to undefined (not null or empty object).
  4. Validate the config before passing: `Array.isArray(x) && x.every(v => typeof v === 'string')`.

Example fix

// before
CypressEsm({ ignoreModuleList: 'lodash', ignoreImportList: { react: true } })
// after
CypressEsm({ ignoreModuleList: ['lodash'], ignoreImportList: ['react'] })
Defensive patterns

Strategy: type-guard

Validate before calling

function asStringArray(v: unknown): string[] | undefined {
  if (v == null) return undefined
  if (!Array.isArray(v) || v.some(x => typeof x !== 'string')) throw new Error('expected string[]')
  return v
}

Type guard

const isStringArrayOrUndef = (v: unknown): v is string[] | undefined => v == null || (Array.isArray(v) && v.every(x => typeof x === 'string'))

Prevention

When it happens

Trigger: Instantiating `CypressEsm({ ignoreList: ... })` (or ignoreModuleList / ignoreImportList) with a non-array value or an array containing non-strings. assertIsArrayOrUndefined runs at plugin creation time, so the throw happens during Vite plugin setup, before the server starts.

Common situations: Passing a single string instead of an array (`ignoreModuleList: 'lodash'`), passing an object keyed by module name, or a config builder that conditionally includes a non-string element.

Related errors


AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12). Data as JSON: /api/errors/ab89aefd0631d8e2. Report an issue: GitHub.