handlebars-lang/handlebars.js · error · Exception
Compile completed with content left on stack
Error message
Compile completed with content left on stack
What it means
An internal compiler sanity check: after generating code for the template, the JavaScriptCompiler expects all value stacks (stackSlot, inlineStack, compileStack) to be empty. Leftover entries mean codegen produced unbalanced push/pop sequences — typically a compiler bug or corrupted AST.
Source
Thrown at lib/handlebars/compiler/javascript-compiler.js:117
firstLoc,
i,
l;
for (i = 0, l = opcodes.length; i < l; i++) {
opcode = opcodes[i];
this.source.currentLocation = opcode.loc;
firstLoc = firstLoc || opcode.loc;
this[opcode.opcode].apply(this, opcode.args);
}
// Flush any trailing content that might be pending.
this.source.currentLocation = firstLoc;
this.pushSource('');
/* v8 ignore next */
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
throw new Exception('Compile completed with content left on stack');
}
if (!this.decorators.isEmpty()) {
this.useDecorators = true;
this.decorators.prepend([
'var decorators = container.decorators, ',
this.lookupPropertyFunctionVarDeclaration(),
';\n',
]);
this.decorators.push('return fn;');
if (asObject) {
// eslint-disable-next-line no-new-func
this.decorators = Function.apply(this, [
'fn',
'props',
'container',View on GitHub (pinned to 13a7a67991)
Solutions
- Upgrade Handlebars to the latest patch release — this is usually a fixed compiler bug.
- Remove custom compiler patches/subclasses overriding opcode emission.
- Reduce the template to a minimal repro and file an issue with the template and version.
- Avoid post-processing the AST before compile in ways that unbalance nodes.
Example fix
// before const compiler = Handlebars.JavaScriptCompiler; compiler.prototype.pushExtra = ...; // custom patch // after Use stock Handlebars compiler; upgrade version instead of patching.
Defensive patterns
Strategy: try-catch
Try / catch
try { return Handlebars.compile(src)(data); } catch (e) { if (/content left on stack/.test(e.message)) { reportCompilerBug(src, Handlebars.VERSION); } throw e; } Prevention
- Do not monkey-patch JavaScriptCompiler internals.
- Keep Handlebars updated to the latest release.
- Minimize AST pre-processing before compile.
When it happens
Trigger: Compiling a template where internal opcode emission leaves values unpopped; custom compiler patches/subclasses that emit extra opcodes; very old Handlebars versions with known codegen bugs.
Common situations: Monkey-patching the compiler or custom node visitors; encountering a Handlebars bug report — users usually hit this via unusual template constructs.
Related errors
AI-assisted analysis of handlebars-lang/handlebars.js@13a7a67991 (2026-09-02).
Data as JSON: /api/errors/5ebbfd295f0b9c99.
Report an issue: GitHub.