{"record":{"id":"5ebbfd295f0b9c99","repo":"handlebars-lang/handlebars.js","slug":"compile-completed-with-content-left-on-stack","errorCode":null,"errorMessage":"Compile completed with content left on stack","messagePattern":"Compile completed with content left on stack","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"lib/handlebars/compiler/javascript-compiler.js","lineNumber":117,"sourceCode":"      firstLoc,\n      i,\n      l;\n\n    for (i = 0, l = opcodes.length; i < l; i++) {\n      opcode = opcodes[i];\n\n      this.source.currentLocation = opcode.loc;\n      firstLoc = firstLoc || opcode.loc;\n      this[opcode.opcode].apply(this, opcode.args);\n    }\n\n    // Flush any trailing content that might be pending.\n    this.source.currentLocation = firstLoc;\n    this.pushSource('');\n\n    /* v8 ignore next */\n    if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {\n      throw new Exception('Compile completed with content left on stack');\n    }\n\n    if (!this.decorators.isEmpty()) {\n      this.useDecorators = true;\n\n      this.decorators.prepend([\n        'var decorators = container.decorators, ',\n        this.lookupPropertyFunctionVarDeclaration(),\n        ';\\n',\n      ]);\n      this.decorators.push('return fn;');\n\n      if (asObject) {\n        // eslint-disable-next-line no-new-func\n        this.decorators = Function.apply(this, [\n          'fn',\n          'props',\n          'container',","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/handlebars-lang/handlebars.js/blob/13a7a679910d2adbfe7f6fad61ce8f98426b0378/lib/handlebars/compiler/javascript-compiler.js#L99-L135","documentation":"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.","triggerScenarios":"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.","commonSituations":"Monkey-patching the compiler or custom node visitors; encountering a Handlebars bug report — users usually hit this via unusual template constructs.","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."],"exampleFix":"// before\nconst compiler = Handlebars.JavaScriptCompiler;\ncompiler.prototype.pushExtra = ...; // custom patch\n// after\nUse stock Handlebars compiler; upgrade version instead of patching.","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return Handlebars.compile(src)(data); } catch (e) { if (/content left on stack/.test(e.message)) { reportCompilerBug(src, Handlebars.VERSION); } throw e; }","preventionTips":["Do not monkey-patch JavaScriptCompiler internals.","Keep Handlebars updated to the latest release.","Minimize AST pre-processing before compile."],"tags":["internal","compiler-bug","codegen"],"backgroundTag":"compiler-internal-error","analyzedSha":"13a7a679910d2adbfe7f6fad61ce8f98426b0378","analyzedAt":"2026-09-02T20:25:07.518Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}