{"id":"da992c42ac30e724","repo":"babel/babel","slug":"caching-was-left-unconfigured-babel-s-plugins-pr","errorCode":null,"errorMessage":"Caching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured\nfor various types of caching, using the first param of their handler functions:\n\nmodule.exports = function(api) {\n  // The API exposes the following:\n\n  // Cache the returned value forever and don't call this function again.\n  api.cache(true);\n\n  // Don't cache at all. Not recommended because it will be very slow.\n  api.cache(false);\n\n  // Cached based on the value of some function. If this function returns a value different from\n  // a previously-encountered value, the plugins will re-evaluate.\n  var env = api.cache(() => process.env.NODE_ENV);\n\n  // If testing for a specific env, we recommend specifics to avoid instantiating a plugin for\n  // any possible NODE_ENV value that might come up during plugin execution.\n  var isProd = api.cache(() => process.env.NODE_ENV === \"production\");\n\n  // .cache(fn) will perform a linear search though instances to find the matching plugin based\n  // based on previous instantiated plugins. If you want to recreate the plugin and discard the\n  // previous instance whenever something changes, you may use:\n  var isProd = api.cache.invalidate(() => process.env.NODE_ENV === \"production\");\n\n  // Note, we also expose the following more-verbose versions of the above examples:\n  api.cache.forever(); // api.cache(true)\n  api.cache.never();   // api.cache(false)\n  api.cache.using(fn); // api.cache(fn)\n\n  // Return the value that will be cached.\n  return { };\n};","messagePattern":"Caching was left unconfigured\\. Babel's plugins, presets, and \\.babelrc\\.js files can be configured\nfor various types of caching, using the first param of their handler functions:\n\nmodule\\.exports = function\\(api\\) (.+?);\n\\};","errorType":"exception","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"packages/babel-core/src/config/files/configuration.ts","lineNumber":369,"sourceCode":"export function* resolveShowConfigPath(\n  dirname: string,\n): Handler<string | null> {\n  const targetPath = process.env.BABEL_SHOW_CONFIG_FOR;\n  if (targetPath != null) {\n    const absolutePath = path.resolve(dirname, targetPath);\n    const stats = (yield* fs.stat(absolutePath))!;\n    if (!stats.isFile()) {\n      throw new Error(\n        `${absolutePath}: BABEL_SHOW_CONFIG_FOR must refer to a regular file, directories are not supported.`,\n      );\n    }\n    return absolutePath;\n  }\n  return null;\n}\n\nfunction throwConfigError(filepath: string): never {\n  throw new ConfigError(\n    `\\\nCaching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured\nfor various types of caching, using the first param of their handler functions:\n\nmodule.exports = function(api) {\n  // The API exposes the following:\n\n  // Cache the returned value forever and don't call this function again.\n  api.cache(true);\n\n  // Don't cache at all. Not recommended because it will be very slow.\n  api.cache(false);\n\n  // Cached based on the value of some function. If this function returns a value different from\n  // a previously-encountered value, the plugins will re-evaluate.\n  var env = api.cache(() => process.env.NODE_ENV);\n\n  // If testing for a specific env, we recommend specifics to avoid instantiating a plugin for","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/babel/babel/blob/06b6eae39da4ce0689fad64e2c48a6375a464208/packages/babel-core/src/config/files/configuration.ts#L351-L387","documentation":"When a config is provided as a factory function (e.g. module.exports = function(api){...}), runConfig invokes it with a ConfigAPI whose cache is queryable. After the function returns, Babel checks `cache.configured()`; if the function never called any api.cache(...) method, throwConfigError fires with a verbose guide. This forces explicit cache declarations so Babel knows when to re-evaluate the factory, preventing accidental re-runs on every file.","triggerScenarios":"A babel.config.js or plugin/preset factory function that returns a config object without ever calling api.cache(true), api.cache(false), api.cache(fn), api.cache.forever(), api.cache.never(), or api.cache.using(fn).","commonSituations":"First-time authors of a JS config factory who copy the object form and forget the cache call; refactoring an object config into a function without adding cache semantics; plugins/presets written as functions omitting the cache directive.","solutions":["Add an explicit cache call at the top of the factory, most commonly api.cache(true) for static configs or api.cache(() => process.env.NODE_ENV) for env-dependent ones.","Use api.cache.never() only if you accept the performance cost of re-running the factory per file.","If the config is truly static, prefer exporting a plain object instead of a function (object configs do not require cache configuration)."],"exampleFix":"// before - throws error 30\nmodule.exports = function(api) {\n  return { presets: ['@babel/preset-env'] };\n};\n\n// after\nmodule.exports = function(api) {\n  api.cache(true);\n  return { presets: ['@babel/preset-env'] };\n};","handlingStrategy":"validation","validationCode":"// Static analysis hint: ensure any config/plugin/preset factory calls api.cache\n// Runtime check is hard since cache.configured() is internal; rely on linting:\n// grep for `module.exports = function` in babel.config.* and assert api.cache usage.","typeGuard":"function isCacheConfiguredCall(src: string): boolean {\n  return /api\\.cache(?:\\.(?:forever|never|using|invalidate)|\\s*\\()/.test(src);\n}","tryCatchPattern":"try { babel.loadOptionsSync(); }\ncatch (err) {\n  if (/Caching was left unconfigured/.test(err.message)) {\n    console.error('Add api.cache(true) (or similar) inside the config factory');\n  }\n  throw err;\n}","preventionTips":["Always add api.cache(...) as the first statement of any config/plugin/preset factory.","Prefer a plain object config when no runtime logic is needed.","Use a lint rule banning function config exports without an api.cache reference."],"tags":["config","caching","factory","babelrc"],"analyzedSha":"06b6eae39da4ce0689fad64e2c48a6375a464208","analyzedAt":"2026-08-03T20:13:43.465Z","schemaVersion":2}