emberjs/ember.js · error

Unexpected block params list on <${name}> component invocati

Error message

Unexpected block params list on <${name}> component invocation: when passing named blocks, the invocation tag cannot take block params

What it means

A component invocation cannot both take block params (|a b|) and pass named blocks (<:x>). Block params correspond to the implicit default block; named blocks replace that with explicit per-name blocks, so the combination is ambiguous and rejected.

Source

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

    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.loc
      );
    }

    if (isPresentArray(this.namedBlocks)) {
      if (hasBlockParams) {
        throw generateSyntaxError(
          `Unexpected block params list on <${name}> component invocation: when passing named blocks, the invocation tag cannot take block params`,
          this.loc
        );
      }

      let seenNames = new Set<string>();

      for (let block of this.namedBlocks) {
        let name = block.name.chars;

        if (seenNames.has(name)) {
          throw generateSyntaxError(
            `Component had two named blocks with the same name, \`<:${name}>\`. Only one block with a given name may be passed`,
            this.loc
          );
        }

        if (

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Remove `as |...|` from the tag and move that content into a <:default> named block
  2. Remove the named blocks if block params are what you actually need
  3. Split into two components if you need both parameterization and named blocks

Example fix

// before
<List as |item|>
  <:header>Items</:header>
</List>
// after
<List>
  <:header>Items</:header>
  <:item as |item|>...</:item>
</List>
Defensive patterns

Strategy: validation

Validate before calling

function blockParamsWithNamedBlocks(src) {
  return /<\w+[^>]*as\s+\|[^|]*\|[^>]*>[\s\S]*<:\w+>/.test(src);
}

Prevention

When it happens

Trigger: Compiling <MyComp as |a b|><:header>h</:header></MyComp> — assertComponent sees namedBlocks present and hasBlockParams true, and throws before deduplicating block names.

Common situations: Adding named blocks to an existing |params| invocation (e.g. when adopting an {{#each}}-style call into named blocks), or converting {{#my-comp as |x|}} to angle brackets while keeping `as |x|`.

Related errors


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