{"record":{"id":"7365ab8bb5bdf5ad","repo":"emberjs/ember.js","slug":"unexpected-named-block-at-the-top-level-of-a-templ","errorCode":null,"errorMessage":"Unexpected named block at the top-level of a template","messagePattern":"Unexpected named block at the top-level of a template","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@glimmer/syntax/lib/v2/normalize.ts","lineNumber":903,"sourceCode":"          case 'HtmlComment':\n            return false;\n          case 'HtmlText':\n            return !/^\\s*$/u.test(c.chars);\n          default:\n            return true;\n        }\n      }).length\n    );\n    this.nonBlockChildren = children.filter(\n      (c): c is ASTv2.ContentNode => !(c instanceof ASTv2.NamedBlock)\n    );\n  }\n}\n\nclass TemplateChildren extends Children {\n  assertTemplate(table: ProgramSymbolTable): ASTv2.Template {\n    if (isPresentArray(this.namedBlocks)) {\n      throw generateSyntaxError(`Unexpected named block at the top-level of a template`, this.loc);\n    }\n\n    return this.block.builder.template(table, this.nonBlockChildren, this.block.loc(this.loc));\n  }\n}\n\nclass BlockChildren extends Children {\n  assertBlock(table: BlockSymbolTable): ASTv2.Block {\n    if (isPresentArray(this.namedBlocks)) {\n      throw generateSyntaxError(`Unexpected named block nested in a normal block`, this.loc);\n    }\n\n    return this.block.builder.block(table, this.nonBlockChildren, this.loc);\n  }\n}\n\nclass ElementChildren extends Children {\n  constructor(","sourceCodeStart":885,"sourceCodeEnd":921,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/syntax/lib/v2/normalize.ts#L885-L921","documentation":"A top-level template (program) may only contain regular content; named blocks (`<:name>`) are only valid inside another element/component invocation as yielded blocks. TemplateChildren.assertTemplate throws when named blocks appear at the program's top level.","triggerScenarios":"Writing `<:header>...</:header>` at the top level of a template file rather than nested inside a component tag.","commonSituations":"Copy-pasting named block syntax out of a component invocation; misunderstanding that `<:yield>`-style blocks belong to elements, not the template root; refactoring a component call away and leaving its named blocks behind.","solutions":["Move the named block inside the element/component that yields it, e.g. `<Modal><:header>...</:header></Modal>`.","If the content should be at the top level, remove the `<:name>` wrapper and keep plain content.","If yielding multiple sections, use `{{yield to=\"name\"}}` with `{{#if (has-block \"name\")}}` in the component instead of top-level named blocks."],"exampleFix":"// before\n<:header>Title</:header>\n\n// after\n<Card>\n  <:header>Title</:header>\n  <:body>Content</:body>\n</Card>","handlingStrategy":"validation","validationCode":"// Template roots must not contain named blocks.\nfunction assertNoTopLevelNamedBlocks(templateTokens) {\n  if (templateTokens.some(t => t.type === 'named-block')) {\n    throw new Error('Named blocks are not allowed at template top level');\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember named blocks only belong inside element/component tags.","Wrap multi-section content in a component invocation that yields to names.","Review refactors that remove component tags so leftover blocks are deleted too."],"tags":["glimmer","template-compiler","named-blocks","syntax-error"],"backgroundTag":"invalid-named-block-usage","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}