emberjs/ember.js · error

<:${name.chars}> is not a valid named block, and named block

Error message

<:${name.chars}> is not a valid named block, and named blocks must begin with a lowercase letter

What it means

Named block names must begin with a lowercase letter (they are analogous to arguments/yield names, not components). assertNamedBlock throws when the name inside `<:Name>` starts with an uppercase character (or otherwise fails the lowercase check).

Source

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

  }

  assertNamedBlock(name: SourceSlice, table: BlockSymbolTable): ASTv2.NamedBlock {
    if (this.el.base.selfClosing) {
      throw generateSyntaxError(
        `<:${name.chars}/> is not a valid named block: named blocks cannot be self-closing`,
        this.loc
      );
    }

    if (isPresentArray(this.namedBlocks)) {
      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);

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Rename the block to start with a lowercase letter: `<:header>...</:header>`.
  2. Update the corresponding `{{yield to="header"}}` call in the component to match the lowercase name.
  3. Update any `has-block("header")` checks to the lowercase name.

Example fix

// before
<Card><:Header>Title</:Header></Card>

// after
<Card><:header>Title</:header></Card>
Defensive patterns

Strategy: validation

Validate before calling

// Enforce lowercase-first named block names.
function assertNamedBlockNameValid(name) {
  if (!/^[a-z]/.test(name)) {
    throw new Error(`<:${name}> must begin with a lowercase letter`);
  }
}

Prevention

When it happens

Trigger: Compiling a template containing `<:Header>...</:Header>` with an uppercase-first block name.

Common situations: Pascal-casing by habit from component names; editors auto-capitalizing block names; team conventions mismatch with Glimmer's named-block rules.

Related errors


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