emberjs/ember.js · error · Error
b.concat requires at least one part
Error message
b.concat requires at least one part
What it means
The AST builder helper `b.concat(parts)` must receive a non-empty array of TextNode/MustacheStatement parts. buildConcat uses isPresentArray to reject empty (or null-length) arrays because an AST ConcatStatement with zero parts is meaningless and would serialize to nothing.
Source
Thrown at packages/@glimmer/syntax/lib/v1/public-builders.ts:139
return b.comment({
value: value,
loc: buildLoc(loc || null),
});
}
function buildMustacheComment(value: string, loc?: SourceLocation): ASTv1.MustacheCommentStatement {
return b.mustacheComment({
value: value,
loc: buildLoc(loc || null),
});
}
function buildConcat(
parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[],
loc?: SourceLocation
): ASTv1.ConcatStatement {
if (!isPresentArray(parts)) {
throw new Error(`b.concat requires at least one part`);
}
return b.concat({
parts,
loc: buildLoc(loc || null),
});
}
// Nodes
export type ElementParts =
| ['attrs', ...AttrSexp[]]
| ['modifiers', ...ModifierSexp[]]
| ['body', ...ASTv1.Statement[]]
| ['comments', ...ElementComment[]]
| ['as', ...string[]]
| ['loc', SourceLocation];
View on GitHub (pinned to 26f97246a8)
Solutions
- Guard before calling: only call b.concat when parts.length > 0.
- When parts is empty, return a TextNode (e.g. b.text('')) instead of a concat.
- Fix the upstream collection logic so at least one part is always produced.
Example fix
// before
return b.concat(parts);
// after
if (parts.length === 0) {
return b.text('');
}
return b.concat(parts); Defensive patterns
Strategy: validation
Validate before calling
function safeConcat(b, parts, loc) {
if (!Array.isArray(parts) || parts.length === 0) return b.text('');
return b.concat(parts, loc);
} Type guard
function isNonEmptyParts(parts) {
return Array.isArray(parts) && parts.length > 0 && parts.every((p) => p && (p.type === 'TextNode' || p.type === 'MustacheStatement'));
} Try / catch
try {
return b.concat(parts);
} catch (e) {
if (e.message.includes('b.concat requires at least one part')) {
return b.text('');
}
throw e;
} Prevention
- Check parts.length before calling b.concat.
- Return a text/empty node for the zero-parts case in AST transforms.
- Unit-test codemods with inputs that produce empty part arrays.
- Prefer b.text for single/static content instead of concat.
When it happens
Trigger: Calling `b.concat([])` (or passing an array that filters down to empty at runtime) when programmatically building Glimmer templates — e.g. AST plugins/codemods that accumulate parts conditionally and end up with none.
Common situations: Writing an Ember template AST transform/codemod that builds `{{...}}` interpolations dynamically; collecting parts from user input that turned out empty.
Related errors
- Compile Error: ${error.problem} @ ${error.span.start}..${err
- Compile Error: ${template.problem} @ ${template.span.start}.
- Compile Error: ${template.problem} @ ${template.span.start}.
- A resolved helper cannot be passed as a named argument as th
- `and` expects at least two arguments, but received ${positio
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/3619772c5b5f2eec.
Report an issue: GitHub.