{"record":{"id":"f8c2899c44adf06e","repo":"emberjs/ember.js","slug":"unexpected-inverse-block-on-decorator","errorCode":null,"errorMessage":"Unexpected inverse block on decorator","messagePattern":"Unexpected inverse block on decorator","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"packages/@handlebars/parser/lib/helpers.js","lineNumber":151,"sourceCode":"    closeStrip: {},\n    loc: locInfo,\n  };\n}\n\nexport function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {\n  if (close && close.path) {\n    validateClose(openBlock, close);\n  }\n\n  let decorator = /\\*/.test(openBlock.open);\n\n  program.blockParams = openBlock.blockParams;\n\n  let inverse, inverseStrip;\n\n  if (inverseAndProgram) {\n    if (decorator) {\n      throw new Exception('Unexpected inverse block on decorator', inverseAndProgram);\n    }\n\n    if (inverseAndProgram.chain) {\n      inverseAndProgram.program.body[0].closeStrip = close.strip;\n    }\n\n    inverseStrip = inverseAndProgram.strip;\n    inverse = inverseAndProgram.program;\n  }\n\n  if (inverted) {\n    inverted = inverse;\n    inverse = program;\n    program = inverted;\n  }\n\n  return {\n    type: decorator ? 'DecoratorBlock' : 'BlockStatement',","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@handlebars/parser/lib/helpers.js#L133-L169","documentation":"Decorators are metadata-only Handlebars nodes and cannot have an inverse ({{else}}) branch. When prepareBlock builds a decorator block and finds an inverse/else program attached, it throws because the construct is meaningless in Handlebars semantics.","triggerScenarios":"A template attaches an {{else}} to a decorator, e.g. {{#my-decorator}}...{{else}}...{{/my-decorator}} where my-decorator was parsed as a decorator (double-curlies with ~ or decorator registration context).","commonSituations":"Confusing decorators with block helpers; copy-pasted block syntax around a decorator; generated templates emitted with else branches for decorator nodes.","solutions":["Remove the {{else}} branch from the decorator block","Convert the construct to a regular block helper if you need inverse behavior","Review template codegen/transform steps that wrap decorators in block syntax"],"exampleFix":"// before\n{{#my-decorator}}\n  main\n{{else}}\n  fallback\n{{/my-decorator}}\n// after\n{{my-decorator}}\n{{#if fallbackNeeded}}fallback{{/if}}","handlingStrategy":"validation","validationCode":"// reject decorator blocks with else before parse\nif (/{{\\s*[#~][^}]*}}[\\s\\S]*{{\\s*else/.test(src)) reviewTemplate(src);","typeGuard":null,"tryCatchPattern":"try { parse(src); } catch (e) { if (/inverse block on decorator/.test(e.message)) { stripElseBranch(src); } throw e; }","preventionTips":["Don't attach {{else}} to decorators or metadata blocks","Generate templates programmatically with a validated AST builder","Lint templates with ember-template-lint"],"tags":["template","handlebars","parser","decorator"],"backgroundTag":"invalid-block-structure","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}