emberjs/ember.js · error

named block <:${name.chars}> cannot have attributes, argumen

Error message

named block <:${name.chars}> cannot have attributes, arguments, or modifiers

What it means

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.

Source

Thrown at packages/@glimmer/syntax/lib/v2/normalize.ts:957

      throw generateSyntaxError(
        `Unexpected named block inside <:${name.chars}> named block: named blocks cannot contain nested named blocks`,
        this.loc
      );
    }

    if (!isLowerCase(name.chars)) {
      throw generateSyntaxError(
        `<:${name.chars}> is not a valid named block, and named blocks must begin with a lowercase letter`,
        this.loc
      );
    }

    if (
      this.el.base.attrs.length > 0 ||
      this.el.base.componentArgs.length > 0 ||
      this.el.base.modifiers.length > 0
    ) {
      throw generateSyntaxError(
        `named block <:${name.chars}> cannot have attributes, arguments, or modifiers`,
        this.loc
      );
    }

    let offsets = SpanList.range(this.nonBlockChildren, this.loc);

    return this.block.builder.namedBlock(
      name,
      this.block.builder.block(table, this.nonBlockChildren, offsets),
      this.loc
    );
  }

  assertElement(name: SourceSlice, hasBlockParams: boolean): ASTv2.SimpleElement {
    if (hasBlockParams) {
      throw generateSyntaxError(
        `Unexpected block params in <${name.chars}>: simple elements cannot have block params`,

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Remove attributes/arguments/modifiers from the named block tag.
  2. Put the class or content wrapper on an inner element: `<:header><div class="x">...</div></:header>`.
  3. Pass parameters through the component invocation's arguments instead, or via `{{yield value}}`.

Example fix

// before
<Card><:header class="card-head">Hi</:header></Card>

// after
<Card><:header><div class="card-head">Hi</div></:header></Card>
Defensive patterns

Strategy: validation

Validate before calling

// Named blocks must be bare tags.
function assertNamedBlockBare(el) {
  if (el.tagName.startsWith(':') &&
      (el.attributes.length || el.modifiers.length || el.args.length)) {
    throw new Error(`${el.tagName} cannot have attributes, arguments, or modifiers`);
  }
}

Prevention

When it happens

Trigger: Compiling `<:header class="x">`, `<:body @foo={{1}}>`, or `<:footer {{on "click" f}}>` — any attribute/argument/modifier on a named block tag.

Common situations: Assuming named blocks behave like elements/components and trying to style or parameterize them; copy-pasting attribute syntax from element tags.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/11b276d6e28dfc37. Report an issue: GitHub.