angular/components · error
There can only be one default row without a when predicate f
Error message
There can only be one default row without a when predicate function.
What it means
CdkTree allows at most one node definition without a `when` predicate, which serves as the default/fallback node renderer. When multiple default node defs are found during content check, the tree cannot decide which to use and throws getTreeMultipleDefaultNodeDefsError (dev mode only).
Source
Thrown at src/cdk/tree/tree.ts:314
// In certain tests, the tree might be destroyed before this is initialized
// in `ngAfterContentInit`.
this._keyManager?.destroy();
}
ngOnInit() {
this._checkTreeControlUsage();
this._initializeDataDiffer();
}
ngAfterViewInit() {
this._viewInit = true;
}
private _updateDefaultNodeDefinition() {
const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);
if (defaultNodeDefs.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw getTreeMultipleDefaultNodeDefsError();
}
this._defaultNodeDef = defaultNodeDefs[0];
}
/**
* Sets the node type for the tree, if it hasn't been set yet.
*
* This will be called by the first node that's rendered in order for the tree
* to determine what data transformations are required.
*/
_setNodeTypeIfUnset(newType: 'flat' | 'nested') {
const currentType = this._nodeType.value;
if (currentType === null) {
this._nodeType.next(newType);
} else if ((typeof ngDevMode === 'undefined' || ngDevMode) && currentType !== newType) {
console.warn(
`Tree is using conflicting node types which can cause unexpected behavior. ` +View on GitHub (pinned to 0411926e7d)
Solutions
- Add a distinct `when` predicate to all but one node definition, e.g. [cdkNodeDef]="let node; when: isFile"
- Keep exactly one catch-all node def without `when`
- Audit all cdk-node-def/matTreeNodeDef children of the tree for missing when bindings
- If templates come from a shared library, ensure the consuming tree only receives one default def
Example fix
// before
<cdk-node-def *cdkNodeDef="let node">Folder: {{node.name}}</cdk-node-def>
<cdk-node-def *cdkNodeDef="let node">File: {{node.name}}</cdk-node-def>
// after
<cdk-node-def *cdkNodeDef="let node; when: isFolder">Folder: {{node.name}}</cdk-node-def>
<cdk-node-def *cdkNodeDef="let node">File: {{node.name}}</cdk-node-def> Defensive patterns
Strategy: validation
Validate before calling
// at content-init time, before rendering the tree
const nodeDefs = getDirectives(treeEl, CdkNodeDef) /* or inspect QueryList in custom code */;
const defaults = nodeDefs.filter(d => !d.when);
if (defaults.length > 1) {
throw new Error('Only one node def may omit a `when` predicate');
} Type guard
interface ValidNodeDefConfig { when?: (data: any, index: number) => boolean; }
function hasSingleDefault(defs: ValidNodeDefConfig[]): defs is [ValidNodeDefConfig, ...ValidNodeDefConfig[]] & { 0: ValidNodeDefConfig } {
return defs.filter(d => !d.when).length <= 1;
} Try / catch
import { getTreeMultipleDefaultNodeDefsError } from '@angular/cdk/tree';
try {
tree.ngAfterContentChecked();
} catch (e) {
if ((e as Error).message.includes('one default row without a when')) {
console.error('Add a when predicate to all but one cdk-node-def');
}
throw e;
} Prevention
- Always tag specialized node defs with a when predicate
- Keep exactly one default (when-less) node def per tree
- Review copied tree templates for leftover unconditional defs
- Enable dev mode in CI so ngDevMode checks surface the duplicate early
When it happens
Trigger: Declaring two or more <cdk-node-def> (or mat-tree node templates) without a when function inside a single <cdk-tree>; ngAfterContentChecked -> _updateDefaultNodeDefinition detects defaultNodeDefs.length > 1.
Common situations: Copy-pasting node templates and forgetting to add a when predicate; refactoring conditions off a node def leaving two unconditional defs; nested trees or templates hoisted via NgTemplateOutlet causing multiple content children to match.
Related errors
- Incorrect tree structure containing detached node.
- Maps event target that uses native events must have `addEven
- Unsupported MatButton appearance "${appearance}"
- A mat-tab-nav-panel must be specified via [tabPanel].
- Cannot specify both the `options` and `interval` inputs at t
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/005af8e998a8db00.
Report an issue: GitHub.