{"record":{"id":"b56c0ffda589a3d2","repo":"emberjs/ember.js","slug":"attempted-to-parse-a-path-expression-but-it-was-n-b56c0f","errorCode":null,"errorMessage":"Attempted to parse a path expression, but it was not valid. Paths must start with a-z or A-Z.","messagePattern":"Attempted to parse a path expression, but it was not valid\\. Paths must start with a-z or A-Z\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts","lineNumber":471,"sourceCode":"      if (head === undefined) {\n        throw generateSyntaxError(\n          `Attempted to parse a path expression, but it was not valid. Paths beginning with @ must start with a-z.`,\n          this.source.spanFor(path.loc)\n        );\n      }\n\n      pathHead = b.atName({\n        name: `@${head}`,\n        loc: this.source.spanFor({\n          start: path.loc.start,\n          end: { line: path.loc.start.line, column: path.loc.start.column + head.length + 1 },\n        }),\n      });\n    } else {\n      const head = parts.shift();\n\n      if (head === undefined) {\n        throw generateSyntaxError(\n          `Attempted to parse a path expression, but it was not valid. Paths must start with a-z or A-Z.`,\n          this.source.spanFor(path.loc)\n        );\n      }\n\n      pathHead = b.var({\n        name: head,\n        loc: this.source.spanFor({\n          start: path.loc.start,\n          end: { line: path.loc.start.line, column: path.loc.start.column + head.length },\n        }),\n      });\n    }\n\n    return b.path({\n      head: pathHead,\n      tail: parts,\n      loc: this.source.spanFor(path.loc),","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts#L453-L489","documentation":"For regular (non-@, non-data) paths, the parser shifts the head segment; if the path has no leading head it cannot be resolved as a variable, so the parser throws. Valid plain paths must start with a letter a-z or A-Z (e.g. this.foo, items, someVar) — the head becomes a variable reference (b.var).","triggerScenarios":"Compiling a template with a PathExpression whose parts list is empty/undefined after stripping data/source markers — e.g. a path expression that normalizes to an empty string reaching the visitor's else branch, where parts.shift() returns undefined.","commonSituations":"Malformed output from template preprocessors/codemods that drop the identifier; hand-edited templates leaving an empty expression like {{ }} that survives earlier validation; macros building paths programmatically with an empty head.","solutions":["Provide the intended variable name at the indicated location: replace the empty/invalid path with a real identifier starting with a letter (e.g. {{this.foo}}).","If you meant the current context, write {{this}} explicitly rather than an empty path.","Re-run or fix the preprocessor/codemod that produced the empty path and inspect its input."],"exampleFix":"// before\n{{}}\n\n// after\n{{this.title}}","handlingStrategy":"validation","validationCode":"// validate plain paths have a letter head before compiling\nfunction assertValidPathHeads(template) {\n  const exprs = template.match(/{{([^}]*)}}/g) || [];\n  for (const e of exprs) {\n    const inner = e.slice(2, -2).trim();\n    if (inner && !/^[a-zA-Z@(\"']/.test(inner)) throw new Error(`Expression must start with a-z or A-Z: ${e}`);\n  }\n}\nassertValidPathHeads(template);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Start every path with an identifier beginning with a letter","Use {{this}} explicitly for current-context references","Review codemod output for empty expressions like {{ }}","Keep a syntax check (precompile) in your build so errors surface early"],"tags":["glimmer","handlebars","template-syntax","invalid-path"],"backgroundTag":"glimmer-invalid-path-head","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}