emberjs/ember.js · error · SyntaxError
Changing context using "../" is not supported in Glimmer
Error message
Changing context using "../" is not supported in Glimmer
What it means
Glimmer's Handlebars parser rejects path expressions that begin with '../' because Glimmer templates have a single, flat scope: dynamic context switching via relative paths was an Ember-Classic (curly component / pre-Glimmer) behavior that no longer exists. The parser inspects every PathExpression's original string during handlebars-node-visitors traversal and throws a syntax error with the offending path's source span.
Source
Thrown at packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts:405
SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression {
const { path, params, hash } = acceptCallNodes(this, sexpr);
return b.sexpr({ path, params, hash, loc: this.source.spanFor(sexpr.loc) });
}
PathExpression(path: HBS.PathExpression): ASTv1.PathExpression {
const { original } = path;
let parts: string[];
if (original.indexOf('/') !== -1) {
if (original.slice(0, 2) === './') {
throw generateSyntaxError(
`Using "./" is not supported in Glimmer and unnecessary`,
this.source.spanFor(path.loc)
);
}
if (original.slice(0, 3) === '../') {
throw generateSyntaxError(
`Changing context using "../" is not supported in Glimmer`,
this.source.spanFor(path.loc)
);
}
if (original.indexOf('.') !== -1) {
throw generateSyntaxError(
`Mixing '.' and '/' in paths is not supported in Glimmer; use only '.' to separate property paths`,
this.source.spanFor(path.loc)
);
}
parts = [path.parts.join('/')];
} else if (original === '.') {
throw generateSyntaxError(
`'.' is not a supported path in Glimmer; check for a path with a trailing '.'`,
this.source.spanFor(path.loc)
);
} else {
parts = path.parts;View on GitHub (pinned to 26f97246a8)
Solutions
- Rewrite the path to reference the value directly via a block param or local variable instead of the parent context (e.g. wrap the each in {{each items as |item|}} and use {{item.name}}).
- Bind the needed outer value to a local: {{#let this.parent as |parent|}} ... {{parent.x}} {{/let}}, or pass it down as an argument/component prop.
- Use a helper or getter in the backing class to expose the outer-scope value instead of reaching up the context stack.
- If this is a generated/legacy template, update the code generator so it no longer emits '../' paths.
Example fix
// before
{{#each items}}
{{title}} of {{../sectionName}}
{{/each}}
// after
{{#each items as |item|}}
{{item.title}} of {{this.sectionName}}
{{/each}} Defensive patterns
Strategy: validation
Validate before calling
// before compiling a template
function assertNoRelativePaths(template) {
const offenders = template.match(/\.\.\/[^\s}]+/g);
if (offenders) throw new Error(`Relative '../' paths not allowed: ${offenders.join(', ')}`);
}
assertNoRelativePaths(template); Prevention
- Always use block params ({{#each list as |item|}}) instead of ../ to access outer scope
- Use {{#let}} to bind outer values to locals in nested scopes
- Enable ember-template-lint rule 'no-implicit-this' and related path rules in CI
- When migrating old Ember templates, grep for '../' before compiling
When it happens
Trigger: Any template compiled with @glimmer/syntax (e.g. via Ember's template compiler) containing a path expression whose original string starts with '../', such as {{../foo}}, {{../item.name}}, or (../parentHelper arg). The check runs in the PathExpression visitor when original.slice(0,3) === '../'.
Common situations: Migrating legacy Ember (pre-Octane / pre-Glimmer) templates to modern Glimmer; copying patterns from old blog posts using contextual components or itemController-era relative paths; nested each/if blocks that relied on ../ to reach an outer scope's variable instead of using block params.
Related errors
- Mixing '.' and '/' in paths is not supported in Glimmer; use
- '.' is not a supported path in Glimmer; check for a path wit
- Attempted to parse a path expression, but it was not valid.
- Attempted to parse a path expression, but it was not valid.
- ${node.path.type} "${node.path.type === 'StringLiteral' ? no
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/d9239923e6dc9a80.
Report an issue: GitHub.