emberjs/ember.js · error

Invalid block parameters syntax: expecting "|" but the tag w

Error message

Invalid block parameters syntax: expecting "|" but the tag was closed prematurely

What it means

While collecting a block param identifier name (AfterStartPipe/BeforeBlockParamName states), the parser expected a `|` (or whitespace to continue the name list) but encountered `>` or `/`, i.e. the tag was closed with the parameters list still unterminated.

Source

Thrown at packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts:482

              );
            },
          };
        } else if (next === '|' || isSpace(next)) {
          let loc = state.start.until(this.offset());

          if (state.name === 'this' || ID_INVERSE_PATTERN.test(state.name)) {
            throw generateSyntaxError(
              `Invalid block parameters syntax: invalid identifier name \`${state.name}\``,
              loc
            );
          }

          element.params.push(b.var({ name: state.name, loc }));

          state = next === '|' ? { state: 'AfterEndPipe' } : { state: 'BeforeBlockParamName' };
          this.tokenizer.consume();
        } else if (next === '>' || next === '/') {
          throw generateSyntaxError(
            `Invalid block parameters syntax: expecting "|" but the tag was closed prematurely`,
            as.start.until(this.offset().move(1))
          );
        } else {
          // slurp up anything else into the name, validate later
          state.name += next;
          this.tokenizer.consume();
        }
      },

      AfterEndPipe: (next: string) => {
        assert(state.state === 'AfterEndPipe', 'bug in block params parser');

        if (isSpace(next)) {
          this.tokenizer.consume();
        } else if (next === '') {
          // The HTML tokenizer ran out of characters, so we are either
          // encountering mustache or <EOF>, HBS side will attach the error

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Add the closing pipe before the tag close: `<Foo as |a b|>`
  2. Count your pipes — one opening and one closing pipe around all identifiers

Example fix

// before
<Foo as |a b>
// after
<Foo as |a b|>
Defensive patterns

Strategy: validation

Validate before calling

// Multi-param lists must close with `|` before the tag close
if (/<[^>]*\bas\s\|[\w\s]+[>\/]/.test(template)) {
  throw new Error('Block params list missing closing "|"');
}

Prevention

When it happens

Trigger: parsePossibleBlockParams (via appendToAttributeName) when next === '>' or '/' during identifier collection — e.g. `<Foo as |a b>` where the closing `|` was omitted after multiple params.

Common situations: Multi-param lists like `as |a b c|` where the last pipe is forgotten; regex-like confusion between `|` and tag close.

Related errors


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