webpack/webpack · error · Error
optimization.concatenateModules can't be used with cacheUnaf
Error message
optimization.concatenateModules can't be used with cacheUnaffected as module concatenation is a global effect
What it means
ModuleConcatenationPlugin inlines multiple modules into a single concatenated module, a graph-global transformation: a module's concatenated form depends on its neighbors. experiments.cacheUnaffected requires per-module independence, so the combination is invalid. At the compilation hook, if compilation.moduleMemCaches is set, the plugin throws before doing any work.
Source
Thrown at lib/optimize/ModuleConcatenationPlugin.js:109
* Format bailout reason.
* @param {string} msg message
* @returns {string} formatted message
*/
const formatBailoutReason = (msg) => `ModuleConcatenation bailout: ${msg}`;
const PLUGIN_NAME = "ModuleConcatenationPlugin";
class ModuleConcatenationPlugin {
/**
* Applies the plugin by registering its hooks on the compiler.
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
const { _backCompat: backCompat } = compiler;
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
if (compilation.moduleMemCaches) {
throw new Error(
"optimization.concatenateModules can't be used with cacheUnaffected as module concatenation is a global effect"
);
}
const moduleGraph = compilation.moduleGraph;
/** @type {Map<Module, string | ((requestShortener: RequestShortener) => string)>} */
const bailoutReasonMap = new Map();
/**
* Sets bailout reason.
* @param {Module} module the module
* @param {string | ((requestShortener: RequestShortener) => string)} reason the reason
*/
const setBailoutReason = (module, reason) => {
setInnerBailoutReason(module, reason);
moduleGraph
.getOptimizationBailout(module)
.push(
typeof reason === "function"View on GitHub (pinned to 318421ea8a)
Solutions
- Disable concatenation: optimization.concatenateModules = false.
- Or disable the experiment: experiments.cacheUnaffected = false.
- Disabling concatenation is the supported way to keep cacheUnaffected; expect a modest increase in module count / runtime overhead.
Example fix
// before
module.exports = {
mode: 'production', // concatenateModules defaults to true
experiments: { cacheUnaffected: true }
};
// after
module.exports = {
mode: 'production',
optimization: { concatenateModules: false },
experiments: { cacheUnaffected: true }
}; Defensive patterns
Strategy: validation
Validate before calling
function assertCacheUnaffectedCompat(config) {
const cu = config.experiments && config.experiments.cacheUnaffected;
const concat = config.optimization && config.optimization.concatenateModules;
if (cu && concat !== false) {
throw new Error('experiments.cacheUnaffected requires optimization.concatenateModules: false');
}
} Prevention
- Pair experiments.cacheUnaffected with optimization.concatenateModules: false.
- Remember concatenateModules is true by default in production.
- Document the supported optimization matrix next to the cacheUnaffected toggle.
When it happens
Trigger: experiments.cacheUnaffected: true combined with optimization.concatenateModules: true (concatenateModules defaults to true in production mode, so this trips unless explicitly disabled).
Common situations: Turning on cacheUnaffected in a production config where concatenateModules is on by default. Adopting the cache experiment for dev-loop speed without adjusting optimization defaults.
Related errors
- optimization.mangleExports can't be used with cacheUnaffecte
- optimization.usedExports can't be used with cacheUnaffected
- Conflicting use of 'optimization.noEmitOnErrors' and 'optimi
- Argument should be an options object. To use defaults, pass
- Cannot parse string options: ${/** @type {Error} */ (err).me
AI-assisted analysis of webpack/webpack@318421ea8a (2026-08-03).
Data as JSON: /data/errors/e5b2ae8fd5ea5689.json.
Report an issue: GitHub.