babel/babel · error · Error
Unexpected replacement overlap.
Error message
Unexpected replacement overlap.
What it means
Tagged-literal templates generate internal placeholder names (prefixed with BABEL_TPL$, e.g. $$BABEL_TPL$0) for the ${} interpolation slots, then merge them with user-named replacements. If a user-supplied replacement key collides with one of these generated names, substitution is ambiguous and rejected.
Source
Thrown at packages/babel-template/src/literal.ts:26
formatter: Formatter<T>,
tpl: string[],
opts: TemplateOpts,
): (_: unknown[]) => (_: unknown) => T {
const { metadata, names } = buildLiteralData(formatter, tpl, opts);
return arg => {
const defaultReplacements: TemplateReplacements = {};
arg.forEach((replacement, i) => {
defaultReplacements[names[i]] = replacement;
});
return (arg: unknown) => {
const replacements = normalizeReplacements(arg);
if (replacements) {
Object.keys(replacements).forEach(key => {
if (Object.hasOwn(defaultReplacements, key)) {
throw new Error("Unexpected replacement overlap.");
}
});
}
return formatter.unwrap(
populatePlaceholders(
metadata,
replacements
? Object.assign(replacements, defaultReplacements)
: defaultReplacements,
),
);
};
};
}
function buildLiteralData<T>(
formatter: Formatter<T>,View on GitHub (pinned to 06b6eae39d)
Solutions
- Rename replacement keys to avoid the BABEL_TPL$ prefix.
- Do not mix positional ${x} substitutions with object keys that resemble the generated names.
- If you need control over names, use the string form template("code", opts) with explicit %%foo%% placeholders.
Example fix
// before
tpl`x`({ '$$BABEL_TPL$0': node })
// after
tpl`x`({ myKey: node }) Defensive patterns
Strategy: validation
Validate before calling
function assertNoBabelPrefix(replacements) {
for (const k of Object.keys(replacements || {})) {
if (k.includes('BABEL_TPL$')) throw new Error(`replacement key ${k} collides with internal prefix`);
}
} Prevention
- Avoid the BABEL_TPL$ substring in replacement keys.
- Do not mix positional ${} slots with object keys that resemble generated names.
- Use string-form templates with %%foo%% for full control of placeholder names.
When it happens
Trigger: Calling a tagged-literal builder with a replacements object whose key matches a generated name, e.g. tpl`...`({ '$$BABEL_TPL$0': node }) or any key beginning with the BABEL_TPL$ prefix.
Common situations: Rare; occurs when user replacement keys happen to match the generated prefix, or when array-form and object-form replacements are mixed in a way that collides.
Related errors
- Error: No substitution given for "${placeholderName}". If th
- Found nothing to return.
- Found multiple statements but wanted one
- '.placeholderAllowlist' must be a Set, null, or undefined
- '.placeholderPattern' must be a RegExp, false, null, or unde
AI-assisted analysis of babel/babel@06b6eae39d (2026-08-03).
Data as JSON: /data/errors/6b34d0236b823261.json.
Report an issue: GitHub.