angular/components · error

Could not find a matching node definition for the provided n

Error message

Could not find a matching node definition for the provided node data.

What it means

When rendering each item of the data stream, the tree calls _getNodeDef(data) to find a cdkTreeNodeDef whose optional when predicate matches the data, falling back to the default (predicate-less) node definition. If no when-matching def exists and there is no default *cdkTreeNodeDef, getTreeMissingMatchingNodeDefError() is thrown because the tree has no template to render that data item.

Source

Thrown at src/cdk/tree/tree.ts:585

    }
  }

  /**
   * Finds the matching node definition that should be used for this node data. If there is only
   * one node definition, it is returned. Otherwise, find the node definition that has a when
   * predicate that returns true with the data. If none return true, return the default node
   * definition.
   */
  _getNodeDef(data: T, i: number): CdkTreeNodeDef<T> {
    if (this._nodeDefs.length === 1) {
      return this._nodeDefs.first!;
    }

    const nodeDef =
      this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;

    if (!nodeDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTreeMissingMatchingNodeDefError();
    }

    return nodeDef!;
  }

  /**
   * Create the embedded view for the data node template and place it in the correct index location
   * within the data node view container.
   */
  insertNode(nodeData: T, index: number, viewContainer?: ViewContainerRef, parentData?: T) {
    const levelAccessor = this._getLevelAccessor();

    const node = this._getNodeDef(nodeData, index);
    const key = this._getExpansionKey(nodeData);

    // Node context that will be provided to created embedded view
    const context = new CdkTreeNodeOutletContext<T>(nodeData);
    context.index = index;

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Add a default fallback template: <cdk-tree-node *cdkTreeNodeDef="let node">...</cdk-tree-node> with no when clause.
  2. Add a when-def covering the unmatched type, e.g. *cdkTreeNodeDef="let node; when: isFile" and ensure the predicate function handles the actual data shape.
  3. Log/inspect the offending data item at the failing index and extend predicates (def.when(i, data)) to match it.
  4. Sanitize/normalize incoming data so every item matches one of the defined predicates before assigning dataSource.

Example fix

// before
<cdk-tree-node *cdkTreeNodeDef="let node; when: isDirectory" cdkTreeNodePadding>...</cdk-tree-node>
// file nodes throw: no matching def

// after
<cdk-tree-node *cdkTreeNodeDef="let node; when: isDirectory" cdkTreeNodePadding>...</cdk-tree-node>
<cdk-tree-node *cdkTreeNodeDef="let node" cdkTreeNodePadding>{{node.name}}</cdk-tree-node>
Defensive patterns

Strategy: validation

Validate before calling

const preds = [(d: any) => d.type === 'folder', (d: any) => d.type === 'file'];
const uncovered = dataSource.filter(d => !preds.some(p => p(d)));
if (uncovered.length) console.error('Node data not covered by any cdkTreeNodeDef when predicate:', uncovered);

Type guard

type TreeData = FolderNode | FileNode;
function isKnownTreeNode(d: unknown): d is TreeData {
  return !!d && typeof d === 'object' && ['folder', 'file'].includes((d as any).type);
}

Try / catch

try {
  this.tree.renderNodeChanges(data);
} catch (e) {
  if (e && String(e.message).includes('matching node definition')) {
    console.warn('Unmatched node data; add a default *cdkTreeNodeDef');
    this.hasDefaultDef = true; // render fallback template
  } else { throw e; }
}

Prevention

When it happens

Trigger: Data contains node objects with kinds (e.g. {type:'file'} vs {type:'folder'}) and only *cdkTreeNodeDef="let node; when: isFolder" templates are defined — a file row then has no matching def; using only when-based defs with no plain *cdkTreeNodeDef fallback; data of unexpected shape/union member slipping in at runtime.

Common situations: Multi-template trees where the backend returns a new node type not covered by any when predicate; union types narrowed incorrectly so the default case is missing; refactoring a single-def tree into multiple when-defs and removing the fallback; conditional rendering where the default def is inside an *ngIf block that is false during the first render.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/3f4ceae2b9b43aaa. Report an issue: GitHub.