handlebars-lang/handlebars.js · error · Exception
replaceStack on non-inline
Error message
replaceStack on non-inline
What it means
replaceStack is an internal JavaScriptCompiler helper only valid while compiling an inline expression (isInline()). Calling it outside inline context would corrupt the emitted expression, so it throws.
Source
Thrown at lib/handlebars/compiler/javascript-compiler.js:935
)
);
this.pendingContent = undefined;
}
if (source) {
this.source.push(source);
}
},
replaceStack: function (callback) {
let prefix = ['('],
stack,
createdStack,
usedLiteral;
/* v8 ignore next */
if (!this.isInline()) {
throw new Exception('replaceStack on non-inline');
}
// We want to merge the inline statement into the replacement statement via ','
let top = this.popStack(true);
if (top instanceof Literal) {
// Literals do not need to be inlined
stack = [top.value];
prefix = ['(', stack];
usedLiteral = true;
} else {
// Get or create the current stack name for use by the inline
createdStack = true;
let name = this.incrStack();
prefix = ['((', this.push(name), ' = ', top, ')'];
stack = this.topStack();
}View on GitHub (pinned to 13a7a67991)
Solutions
- Only call replaceStack inside inline-emission contexts (guard with this.isInline()).
- Use popStack/pushStack directly instead of replaceStack in non-inline code paths.
- Upgrade Handlebars if the error arises from unpatched library code and file a bug with a repro.
Example fix
// before
const ref = this.replaceStack(...); // anywhere in custom opcode
// after
if (this.isInline()) { const ref = this.replaceStack(...); } else { const ref = this.popStack(); } Defensive patterns
Strategy: try-catch
Try / catch
try { return compileWithCustomCompiler(src); } catch (e) { if (/replaceStack on non-inline/.test(e.message)) { fallBackToStockCompiler(); } throw e; } Prevention
- Guard custom compiler code with this.isInline() before replaceStack.
- Prefer popStack/pushStack APIs in non-inline paths.
- Test compiler extensions against the full template corpus.
When it happens
Trigger: Custom JavaScriptCompiler subclass or monkey-patch invoking this.replaceStack when the current opcode emission is not inline; misuse in compiler extensions.
Common situations: Authors of Handlebars compiler plugins/forks extending codegen; internal invariant violation in patched builds.
Related errors
AI-assisted analysis of handlebars-lang/handlebars.js@13a7a67991 (2026-09-02).
Data as JSON: /api/errors/abebd7d3bb248e12.
Report an issue: GitHub.