emberjs/ember.js · error
Component has both <:else> and <:inverse> block. <:inverse>
Error message
Component has both <:else> and <:inverse> block. <:inverse> is an alias for <:else>
What it means
<:else> and <:inverse> are the same block: <:inverse> is an alias for <:else> (used for the false/else branch of conditionals). Passing both would be contradictory, so the normalizer rejects the invocation when both names appear in the seen set.
Source
Thrown at packages/@glimmer/syntax/lib/v2/normalize.ts:1036
}
let seenNames = new Set<string>();
for (let block of this.namedBlocks) {
let name = block.name.chars;
if (seenNames.has(name)) {
throw generateSyntaxError(
`Component had two named blocks with the same name, \`<:${name}>\`. Only one block with a given name may be passed`,
this.loc
);
}
if (
(name === 'inverse' && seenNames.has('else')) ||
(name === 'else' && seenNames.has('inverse'))
) {
throw generateSyntaxError(
`Component has both <:else> and <:inverse> block. <:inverse> is an alias for <:else>`,
this.loc
);
}
seenNames.add(name);
}
return this.namedBlocks;
} else {
return [
this.block.builder.namedBlock(
SourceSlice.synthetic('default'),
this.block.builder.block(table, this.nonBlockChildren, this.loc),
this.loc
),
];
}View on GitHub (pinned to 26f97246a8)
Solutions
- Keep only <:else> (the canonical name) and delete the <:inverse> block
- Or keep <:inverse> and delete <:else>, matching the component's documented convention
- Merge the content of both blocks into the single retained block if both bodies were intended
Example fix
// before
<Toggle>
<:inverse>Off</:inverse>
<:else>Disabled</:else>
</Toggle>
// after
<Toggle>
<:else>
Off
Disabled
</:else>
</Toggle> Defensive patterns
Strategy: validation
Validate before calling
function hasElseAndInverse(src) {
return /<:else>/.test(src) && /<:inverse>/.test(src);
} Prevention
- Pick one convention (usually <:else>) per codebase and document it
- Search for `<:inverse>` when onboarding components that use `<:else>`
- Treat them as aliases in code review checklists
When it happens
Trigger: Compiling an invocation that includes both blocks, e.g. <If @cond><:inverse>a</:inverse><:else>b</:else></If> — the dedup loop's alias check (name==='inverse' && seenNames.has('else') or vice versa) throws.
Common situations: Incremental migration where one author wrote <:else> and another added <:inverse> (or vice versa), or confusion about which alias spelling the component supports.
Related errors
- Invalid named block named detected, you may have created a n
- Unexpected named block <:foo> inside <${name.chars}> HTML el
- Unexpected named blocks inside <${name.chars}> HTML element
- Unexpected content inside <${name}> component invocation: wh
- Unexpected block params list on <${name}> component invocati
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/f4929db8a26292d8.
Report an issue: GitHub.