{"record":{"id":"11b276d6e28dfc37","repo":"emberjs/ember.js","slug":"named-block-name-chars-cannot-have-attribute","errorCode":null,"errorMessage":"named block <:${name.chars}> cannot have attributes, arguments, or modifiers","messagePattern":"named block <:(.+?)> cannot have attributes, arguments, or modifiers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@glimmer/syntax/lib/v2/normalize.ts","lineNumber":957,"sourceCode":"      throw generateSyntaxError(\n        `Unexpected named block inside <:${name.chars}> named block: named blocks cannot contain nested named blocks`,\n        this.loc\n      );\n    }\n\n    if (!isLowerCase(name.chars)) {\n      throw generateSyntaxError(\n        `<:${name.chars}> is not a valid named block, and named blocks must begin with a lowercase letter`,\n        this.loc\n      );\n    }\n\n    if (\n      this.el.base.attrs.length > 0 ||\n      this.el.base.componentArgs.length > 0 ||\n      this.el.base.modifiers.length > 0\n    ) {\n      throw generateSyntaxError(\n        `named block <:${name.chars}> cannot have attributes, arguments, or modifiers`,\n        this.loc\n      );\n    }\n\n    let offsets = SpanList.range(this.nonBlockChildren, this.loc);\n\n    return this.block.builder.namedBlock(\n      name,\n      this.block.builder.block(table, this.nonBlockChildren, offsets),\n      this.loc\n    );\n  }\n\n  assertElement(name: SourceSlice, hasBlockParams: boolean): ASTv2.SimpleElement {\n    if (hasBlockParams) {\n      throw generateSyntaxError(\n        `Unexpected block params in <${name.chars}>: simple elements cannot have block params`,","sourceCodeStart":939,"sourceCodeEnd":975,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/syntax/lib/v2/normalize.ts#L939-L975","documentation":"A named block is purely a container for yielded content; it cannot carry HTML attributes, arguments (`@foo=...`), or element modifiers. The normalizer throws when a `<:name>` element has any attrs, component args, or modifiers.","triggerScenarios":"Compiling `<:header class=\"x\">`, `<:body @foo={{1}}>`, or `<:footer {{on \"click\" f}}>` — any attribute/argument/modifier on a named block tag.","commonSituations":"Assuming named blocks behave like elements/components and trying to style or parameterize them; copy-pasting attribute syntax from element tags.","solutions":["Remove attributes/arguments/modifiers from the named block tag.","Put the class or content wrapper on an inner element: `<:header><div class=\"x\">...</div></:header>`.","Pass parameters through the component invocation's arguments instead, or via `{{yield value}}`."],"exampleFix":"// before\n<Card><:header class=\"card-head\">Hi</:header></Card>\n\n// after\n<Card><:header><div class=\"card-head\">Hi</div></:header></Card>","handlingStrategy":"validation","validationCode":"// Named blocks must be bare tags.\nfunction assertNamedBlockBare(el) {\n  if (el.tagName.startsWith(':') &&\n      (el.attributes.length || el.modifiers.length || el.args.length)) {\n    throw new Error(`${el.tagName} cannot have attributes, arguments, or modifiers`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat named blocks as pure content containers — no attributes, args, or modifiers.","Style yielded content with a wrapper element inside the block.","Pass data via component arguments or `{{yield value}}`, not block attributes."],"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"}