{"record":{"id":"21b4414a1af7dd4d","repo":"gatsbyjs/gatsby","slug":"keepdynamicimports-option-needs-to-be-set","errorCode":null,"errorMessage":"keepDynamicImports option needs to be set","messagePattern":"keepDynamicImports option needs to be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/babel-preset-gatsby-package/lib/babel-transform-mark-to-keep-dynamic-import.js","lineNumber":28,"sourceCode":" */\n\n/**\n * @typedef {Object} IPluginOptions\n * @property {Array<string>} keepDynamicImports\n */\n\n/**\n *\n * @param {{ types: BabelTypes }} _unused\n * @param {Partial<IPluginOptions>} opts\n * @returns {PluginObj}\n */\nmodule.exports = function keepDynamicImports(\n  _unused,\n  opts\n) {\n  if (!opts.keepDynamicImports) {\n    throw new Error(`keepDynamicImports option needs to be set`)\n  } else if (!Array.isArray(opts.keepDynamicImports)) {\n    throw new Error(`keepDynamicImports option needs to be an array`)\n  }\n\n  const absolutePaths = opts.keepDynamicImports.map(p => path.resolve(p))\n\n  return {\n    name: `babel-transform-mark-to-keep-dynamic-import`,\n    visitor: {\n      Program() {\n        const filename = this.file?.opts?.filename\n        if (!filename) {\n          return\n        }\n\n        if (absolutePaths.includes(filename)) {\n          // this is big hack - it relies on some babel plugins internal to basically\n          // do early return ( https://github.com/babel/babel/blob/3526b79c87863052f1c61ec0c49c0fc287ba32e6/packages/babel-plugin-transform-modules-commonjs/src/index.ts#L174 )","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/babel-preset-gatsby-package/lib/babel-transform-mark-to-keep-dynamic-import.js#L10-L46","documentation":"Thrown by `babel-transform-mark-to-keep-dynamic-import` (babel-transform-mark-to-keep-dynamic-import.js:28) at plugin setup when `opts.keepDynamicImports` is falsy. The plugin's job is to mark certain dynamic `import()` calls so they survive babel transformation; without the list of paths to keep, it has nothing to do and refuses to run.","triggerScenarios":"Registering the plugin without `keepDynamicImports`; passing `{ keepDynamicImports: null }`; the preset not forwarding this option to the plugin.","commonSituations":"Configuring babel-preset-gatsby-package manually and omitting the option; integrating the plugin standalone; refactoring the preset and losing the option plumbing.","solutions":["Pass `keepDynamicImports` as an array of module paths: `{ keepDynamicImports: ['gatsby-plugin-theme-ui'] }`.","If you do not need to preserve any dynamic imports, remove the plugin entirely.","Ensure the preset forwards `keepDynamicImports` down to the plugin."],"exampleFix":"// before\nkeepDynamicImports(_unused, {})\n\n// after\nkeepDynamicImports(_unused, { keepDynamicImports: ['gatsby-plugin-theme-ui'] })","handlingStrategy":"validation","validationCode":"function pluginHasKeepDynamicImportsOption(opts) {\n  return Boolean(opts && opts.keepDynamicImports)\n}","typeGuard":"/** @returns {opts is { keepDynamicImports: unknown[] }} */\nfunction hasKeepDynamicImportsArray(opts) {\n  return opts != null && Array.isArray(opts.keepDynamicImports)\n}","tryCatchPattern":null,"preventionTips":["Always pass keepDynamicImports as an array of paths.","Omit the plugin entirely if you have no dynamic imports to preserve.","Forward this option through any preset wrapper."],"tags":["babel","config","dynamic-import","compiler"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}