gatsbyjs/gatsby · error

keepDynamicImports option needs to be an array

Error message

keepDynamicImports option needs to be an array

What it means

Thrown by `babel-transform-mark-to-keep-dynamic-import` (babel-transform-mark-to-keep-dynamic-import.js:30) when `opts.keepDynamicImports` is set but is not an array. The plugin calls `.map()` on it, so a non-array would crash later; this guard fails fast with a clear message instead.

Source

Thrown at packages/babel-preset-gatsby-package/lib/babel-transform-mark-to-keep-dynamic-import.js:30

/**
 * @typedef {Object} IPluginOptions
 * @property {Array<string>} keepDynamicImports
 */

/**
 *
 * @param {{ types: BabelTypes }} _unused
 * @param {Partial<IPluginOptions>} opts
 * @returns {PluginObj}
 */
module.exports = function keepDynamicImports(
  _unused,
  opts
) {
  if (!opts.keepDynamicImports) {
    throw new Error(`keepDynamicImports option needs to be set`)
  } else if (!Array.isArray(opts.keepDynamicImports)) {
    throw new Error(`keepDynamicImports option needs to be an array`)
  }

  const absolutePaths = opts.keepDynamicImports.map(p => path.resolve(p))

  return {
    name: `babel-transform-mark-to-keep-dynamic-import`,
    visitor: {
      Program() {
        const filename = this.file?.opts?.filename
        if (!filename) {
          return
        }

        if (absolutePaths.includes(filename)) {
          // this is big hack - it relies on some babel plugins internal to basically
          // do early return ( https://github.com/babel/babel/blob/3526b79c87863052f1c61ec0c49c0fc287ba32e6/packages/babel-plugin-transform-modules-commonjs/src/index.ts#L174 )
          // on top of that `BabelFile` doesn't expose delete for the metadata,
          // so we reach into internal `_map` to delete it

View on GitHub (pinned to 8b06340921)

Solutions

  1. Wrap the value in an array: `keepDynamicImports: ['gatsby-plugin-theme-ui']`.
  2. Confirm the option type against the JSDoc (`@property {Array<string>} keepDynamicImports`).

Example fix

// before
keepDynamicImports(_unused, { keepDynamicImports: 'gatsby-plugin-theme-ui' })

// after
keepDynamicImports(_unused, { keepDynamicImports: ['gatsby-plugin-theme-ui'] })
Defensive patterns

Strategy: validation

Validate before calling

function keepDynamicImportsIsArray(opts) {
  return Array.isArray(opts && opts.keepDynamicImports)
}

Type guard

/** @returns {opts is { keepDynamicImports: string[] }} */
function isStringArray(v) {
  return Array.isArray(v) && v.every(x => typeof x === 'string')
}

Prevention

When it happens

Trigger: Passing `keepDynamicImports: 'gatsby-plugin-theme-ui'` (string instead of array); passing an object; passing a single value rather than a list.

Common situations: Misreading the option type from docs and passing a single string; copy-pasting a config snippet that uses the wrong shape.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/c4ecccd9634e58be. Report an issue: GitHub.