emberjs/ember.js · error
Unexpected named blocks inside <${name.chars}> HTML element
Error message
Unexpected named blocks inside <${name.chars}> HTML element (${printedNames}) What it means
Same rule as the single-named-block case: plain HTML elements cannot contain any named blocks. When more than one named block (<:a>, <:b>, ...) appears inside an HTML element, the compiler reports all offending block names to help locate the mistake.
Source
Thrown at packages/@glimmer/syntax/lib/v2/normalize.ts:990
assertElement(name: SourceSlice, hasBlockParams: boolean): ASTv2.SimpleElement {
if (hasBlockParams) {
throw generateSyntaxError(
`Unexpected block params in <${name.chars}>: simple elements cannot have block params`,
this.loc
);
}
if (isPresentArray(this.namedBlocks)) {
let names = this.namedBlocks.map((b) => b.name);
if (names.length === 1) {
throw generateSyntaxError(
`Unexpected named block <:foo> inside <${name.chars}> HTML element`,
this.loc
);
} else {
let printedNames = names.map((n) => `<:${n.chars}>`).join(', ');
throw generateSyntaxError(
`Unexpected named blocks inside <${name.chars}> HTML element (${printedNames})`,
this.loc
);
}
}
return this.el.simple(name, this.nonBlockChildren, this.loc);
}
assertComponent(
name: string,
table: BlockSymbolTable,
hasBlockParams: boolean
): PresentArray<ASTv2.NamedBlock> {
if (isPresentArray(this.namedBlocks) && this.hasSemanticContent) {
throw generateSyntaxError(
`Unexpected content inside <${name}> component invocation: when using named blocks, the tag cannot contain other content`,
this.locView on GitHub (pinned to 26f97246a8)
Solutions
- Convert the tag to a component invocation if blocks are intended (capitalize/namespace the name)
- Remove the named blocks and put content directly inside the element
- Split content into multiple elements instead of named blocks
Example fix
// before <section> <:header>Title</:header> <:body>Content</:body> </section> // after <Section> <:header>Title</:header> <:body>Content</:body> </Section>
Defensive patterns
Strategy: validation
Validate before calling
function hasMultipleNamedBlocksInElement(template) {
const m = template.match(/<:\w+>/g) || [];
return m.length > 1;
} Prevention
- When wrappers are needed, create a real component instead of faking blocks on HTML tags
- Keep capitalized component names so block syntax reads correctly
- Lint templates for `<:name>` occurrences inside lowercase tags
When it happens
Trigger: Compiling a template with two or more named blocks inside a plain HTML element, e.g. <div><:a>x</:a><:b>y</:b></div> — assertElement builds printedNames from the block names and throws.
Common situations: Mistaking an HTML tag for a component invocation (e.g. writing <ul> instead of <Ul> or <MyList>), or authoring wrapper markup by hand that mimics yieldable component syntax.
Related errors
- Invalid named block named detected, you may have created a n
- Unexpected named block <:foo> inside <${name.chars}> HTML el
- Unexpected content inside <${name}> component invocation: wh
- Unexpected block params list on <${name}> component invocati
- Component had two named blocks with the same name, `<:${name
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/5e92ddc3296d02f1.
Report an issue: GitHub.