emberjs/ember.js · error
Invalid block parameters syntax: modifiers cannot follow par
Error message
Invalid block parameters syntax: modifiers cannot follow parameters list
What it means
Glimmer's block-params lookahead parser (parsePossibleBlockParams) accepts `|a b|` after a tag name only if the tag is then closed. When a mustache (modifier, e.g. `{{action}}`) appears after the parameters list, the tokenizer's pendingError.mustache callback fires, because modifiers cannot follow a block-params list in Handlebars syntax.
Source
Thrown at packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts:505
// 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
// to the next span
state = { state: 'Done' };
this.pendingError = {
mustache(loc: src.SourceSpan) {
throw generateSyntaxError(
`Invalid block parameters syntax: modifiers cannot follow parameters list`,
loc
);
},
eof(loc: src.SourceOffset) {
throw generateSyntaxError(
`Invalid block parameters syntax: expecting the tag to be closed with ">" or "/>" after parameters list`,
as.start.until(loc)
);
},
};
} else if (next === '>' || next === '/') {
// Don't consume, let the normal tokenizer code handle the next steps
state = { state: 'Done' };
} else {
// Slurp up the next "token" for the error span
state = {
state: 'Error',View on GitHub (pinned to 26f97246a8)
Solutions
- Remove the block params list from the element tag; block params belong on curly block form (`{{#foo as |a b|}}`)
- Remove the element modifier if block-params-like syntax was intentional elsewhere
- Wrap the content in a real block or component that supports `as |...|`
Example fix
// before
<div |a b| {{on "click" this.go}}>...</div>
// after
<div {{on "click" this.go}}>...</div> Defensive patterns
Strategy: validation
Validate before calling
// crude guard before parsing
if (/^<[^>]*\|[^>]*\|[^>]*\{\{/m.test(template)) {
throw new Error('Block params cannot be followed by a modifier mustache on the tag');
} Try / catch
try { parse(template) } catch (e) { if (/modifiers cannot follow parameters list/.test(e.message)) { /* report template location / fallback */ } else throw e; } Prevention
- Never put `|a b|` on element tags; use it only in curly block form `{{#x as |a b|}}`
- Run a template linter (ember-template-lint) before building
- Preview templates in an editor with Glimmer syntax highlighting
When it happens
Trigger: Parsing a template where a mustache/modifier follows a block params list on an element, e.g. `<div |a b| {{action}}>`; the mustache handler throws the pending error.
Common situations: Hand-written components mixing block params with element modifiers; refactoring `<div ... as |a b|>` style from block form onto the tag itself; misunderstanding that `as |x|` only applies in block form, not on element tags.
Related errors
- Invalid block parameters syntax: block parameters must be pr
- Invalid block parameters syntax: expecting at least one spac
- Invalid block parameters syntax: mustaches cannot be used in
- Invalid block parameters syntax: expecting the tag to be clo
- Invalid block parameters syntax: empty parameters list, expe
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/7aabe62451351937.
Report an issue: GitHub.