{"record":{"id":"813b65d76293d076","repo":"emberjs/ember.js","slug":"invalid-block-parameters-syntax-expecting-the-tag","errorCode":null,"errorMessage":"Invalid block parameters syntax: expecting the tag to be closed with \">\" or \"/>\" after parameters list","messagePattern":"Invalid block parameters syntax: expecting the tag to be closed with \">\" or \"/>\" after parameters list","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts","lineNumber":412,"sourceCode":"\n      BeforeBlockParamName: (next: string) => {\n        assert(state.state === 'BeforeBlockParamName', 'bug in block params parser');\n\n        if (isSpace(next)) {\n          this.tokenizer.consume();\n        } else if (next === '') {\n          // The HTML tokenizer ran out of characters, so we are either\n          // encountering mustache or <EOF>\n          state = { state: 'Done' };\n          this.pendingError = {\n            mustache(loc: src.SourceSpan) {\n              throw generateSyntaxError(\n                `Invalid block parameters syntax: mustaches cannot be used inside parameters list`,\n                loc\n              );\n            },\n            eof(loc: src.SourceOffset) {\n              throw generateSyntaxError(\n                `Invalid block parameters syntax: expecting the tag to be closed with \">\" or \"/>\" after parameters list`,\n                as.start.until(loc)\n              );\n            },\n          };\n        } else if (next === '|') {\n          if (element.params.length === 0) {\n            // Following Handlebars and treat empty block params a syntax error\n            throw generateSyntaxError(\n              `Invalid block parameters syntax: empty parameters list, expecting at least one identifier`,\n              as.start.until(this.offset().move(1))\n            );\n          } else {\n            state = { state: 'AfterEndPipe' };\n            this.tokenizer.consume();\n          }\n        } else if (next === '>' || next === '/') {\n          throw generateSyntaxError(","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts#L394-L430","documentation":"When the template reaches end-of-file while the parser is still inside a block parameters list, it cannot complete the tag, so it throws this error spanning from the `as` to EOF. The parameters list was never closed and the tag never terminated with `>` or `/>`.","triggerScenarios":"eof() handler invoked while parsePossibleBlockParams is pending — templates truncated inside the params list, e.g. `<Foo as |a b` with no closing pipe or tag close.","commonSituations":"Truncated template files (failed saves, partial pastes); heredocs or string templates cut off; editors deleting trailing lines.","solutions":["Close the parameters list and tag: `<Foo as |a b|>` or `<Foo as |a b|/>`","Check the template file was saved/complete and not truncated"],"exampleFix":"// before\n<Foo as |a b\n// after\n<Foo as |a b|>{{a}}</Foo>","handlingStrategy":"validation","validationCode":"// Check template completeness: balanced pipes inside tag opens and a closing `>`\nconst opens = template.match(/<[^>]*\\bas\\s\\|[^>]*$/);\nif (opens) throw new Error('Tag with block params is unterminated at EOF');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify template files are fully saved and not truncated before compiling","Lint for unbalanced `<` / `>` and `|` in templates","Compile templates in CI to surface truncation early"],"tags":["glimmer","handlebars","template-syntax","block-params","eof"],"backgroundTag":"invalid-block-params-syntax","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}