{"record":{"id":"abebd7d3bb248e12","repo":"handlebars-lang/handlebars.js","slug":"replacestack-on-non-inline","errorCode":null,"errorMessage":"replaceStack on non-inline","messagePattern":"replaceStack on non-inline","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"lib/handlebars/compiler/javascript-compiler.js","lineNumber":935,"sourceCode":"        )\n      );\n      this.pendingContent = undefined;\n    }\n\n    if (source) {\n      this.source.push(source);\n    }\n  },\n\n  replaceStack: function (callback) {\n    let prefix = ['('],\n      stack,\n      createdStack,\n      usedLiteral;\n\n    /* v8 ignore next */\n    if (!this.isInline()) {\n      throw new Exception('replaceStack on non-inline');\n    }\n\n    // We want to merge the inline statement into the replacement statement via ','\n    let top = this.popStack(true);\n\n    if (top instanceof Literal) {\n      // Literals do not need to be inlined\n      stack = [top.value];\n      prefix = ['(', stack];\n      usedLiteral = true;\n    } else {\n      // Get or create the current stack name for use by the inline\n      createdStack = true;\n      let name = this.incrStack();\n\n      prefix = ['((', this.push(name), ' = ', top, ')'];\n      stack = this.topStack();\n    }","sourceCodeStart":917,"sourceCodeEnd":953,"githubUrl":"https://github.com/handlebars-lang/handlebars.js/blob/13a7a679910d2adbfe7f6fad61ce8f98426b0378/lib/handlebars/compiler/javascript-compiler.js#L917-L953","documentation":"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.","triggerScenarios":"Custom JavaScriptCompiler subclass or monkey-patch invoking this.replaceStack when the current opcode emission is not inline; misuse in compiler extensions.","commonSituations":"Authors of Handlebars compiler plugins/forks extending codegen; internal invariant violation in patched builds.","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."],"exampleFix":"// before\nconst ref = this.replaceStack(...); // anywhere in custom opcode\n// after\nif (this.isInline()) { const ref = this.replaceStack(...); } else { const ref = this.popStack(); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return compileWithCustomCompiler(src); } catch (e) { if (/replaceStack on non-inline/.test(e.message)) { fallBackToStockCompiler(); } throw e; }","preventionTips":["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."],"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"}