{"record":{"id":"2e9a35aee2f7c47e","repo":"emberjs/ember.js","slug":"invalid-block-parameters-syntax-expecting-but","errorCode":null,"errorMessage":"Invalid block parameters syntax: expecting \"|\" but the tag was closed prematurely","messagePattern":"Invalid block parameters syntax: expecting \"\\|\" but the tag was closed prematurely","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts","lineNumber":482,"sourceCode":"              );\n            },\n          };\n        } else if (next === '|' || isSpace(next)) {\n          let loc = state.start.until(this.offset());\n\n          if (state.name === 'this' || ID_INVERSE_PATTERN.test(state.name)) {\n            throw generateSyntaxError(\n              `Invalid block parameters syntax: invalid identifier name \\`${state.name}\\``,\n              loc\n            );\n          }\n\n          element.params.push(b.var({ name: state.name, loc }));\n\n          state = next === '|' ? { state: 'AfterEndPipe' } : { state: 'BeforeBlockParamName' };\n          this.tokenizer.consume();\n        } else if (next === '>' || next === '/') {\n          throw generateSyntaxError(\n            `Invalid block parameters syntax: expecting \"|\" but the tag was closed prematurely`,\n            as.start.until(this.offset().move(1))\n          );\n        } else {\n          // slurp up anything else into the name, validate later\n          state.name += next;\n          this.tokenizer.consume();\n        }\n      },\n\n      AfterEndPipe: (next: string) => {\n        assert(state.state === 'AfterEndPipe', '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>, HBS side will attach the error","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts#L464-L500","documentation":"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.","triggerScenarios":"parsePossibleBlockParams (via appendToAttributeName) when next === '>' or '/' during identifier collection — e.g. `<Foo as |a b>` where the closing `|` was omitted after multiple params.","commonSituations":"Multi-param lists like `as |a b c|` where the last pipe is forgotten; regex-like confusion between `|` and tag close.","solutions":["Add the closing pipe before the tag close: `<Foo as |a b|>`","Count your pipes — one opening and one closing pipe around all identifiers"],"exampleFix":"// before\n<Foo as |a b>\n// after\n<Foo as |a b|>","handlingStrategy":"validation","validationCode":"// Multi-param lists must close with `|` before the tag close\nif (/<[^>]*\\bas\\s\\|[\\w\\s]+[>\\/]/.test(template)) {\n  throw new Error('Block params list missing closing \"|\"');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["For `as |a b c|`, always end with a pipe before `>`","Format templates with a glimmer-aware formatter to keep params consistent"],"tags":["glimmer","handlebars","template-syntax","block-params"],"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"}