{"record":{"id":"3f4ceae2b9b43aaa","repo":"angular/components","slug":"could-not-find-a-matching-node-definition-for-the","errorCode":null,"errorMessage":"Could not find a matching node definition for the provided node data.","messagePattern":"Could not find a matching node definition for the provided node data\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/tree/tree.ts","lineNumber":585,"sourceCode":"    }\n  }\n\n  /**\n   * Finds the matching node definition that should be used for this node data. If there is only\n   * one node definition, it is returned. Otherwise, find the node definition that has a when\n   * predicate that returns true with the data. If none return true, return the default node\n   * definition.\n   */\n  _getNodeDef(data: T, i: number): CdkTreeNodeDef<T> {\n    if (this._nodeDefs.length === 1) {\n      return this._nodeDefs.first!;\n    }\n\n    const nodeDef =\n      this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;\n\n    if (!nodeDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw getTreeMissingMatchingNodeDefError();\n    }\n\n    return nodeDef!;\n  }\n\n  /**\n   * Create the embedded view for the data node template and place it in the correct index location\n   * within the data node view container.\n   */\n  insertNode(nodeData: T, index: number, viewContainer?: ViewContainerRef, parentData?: T) {\n    const levelAccessor = this._getLevelAccessor();\n\n    const node = this._getNodeDef(nodeData, index);\n    const key = this._getExpansionKey(nodeData);\n\n    // Node context that will be provided to created embedded view\n    const context = new CdkTreeNodeOutletContext<T>(nodeData);\n    context.index = index;","sourceCodeStart":567,"sourceCodeEnd":603,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/tree/tree.ts#L567-L603","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add a default fallback template: <cdk-tree-node *cdkTreeNodeDef=\"let node\">...</cdk-tree-node> with no when clause.","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.","Log/inspect the offending data item at the failing index and extend predicates (def.when(i, data)) to match it.","Sanitize/normalize incoming data so every item matches one of the defined predicates before assigning dataSource."],"exampleFix":"// before\n<cdk-tree-node *cdkTreeNodeDef=\"let node; when: isDirectory\" cdkTreeNodePadding>...</cdk-tree-node>\n// file nodes throw: no matching def\n\n// after\n<cdk-tree-node *cdkTreeNodeDef=\"let node; when: isDirectory\" cdkTreeNodePadding>...</cdk-tree-node>\n<cdk-tree-node *cdkTreeNodeDef=\"let node\" cdkTreeNodePadding>{{node.name}}</cdk-tree-node>","handlingStrategy":"validation","validationCode":"const preds = [(d: any) => d.type === 'folder', (d: any) => d.type === 'file'];\nconst uncovered = dataSource.filter(d => !preds.some(p => p(d)));\nif (uncovered.length) console.error('Node data not covered by any cdkTreeNodeDef when predicate:', uncovered);","typeGuard":"type TreeData = FolderNode | FileNode;\nfunction isKnownTreeNode(d: unknown): d is TreeData {\n  return !!d && typeof d === 'object' && ['folder', 'file'].includes((d as any).type);\n}","tryCatchPattern":"try {\n  this.tree.renderNodeChanges(data);\n} catch (e) {\n  if (e && String(e.message).includes('matching node definition')) {\n    console.warn('Unmatched node data; add a default *cdkTreeNodeDef');\n    this.hasDefaultDef = true; // render fallback template\n  } else { throw e; }\n}","preventionTips":["Always include a predicate-less default *cdkTreeNodeDef as a catch-all fallback.","Cover every member of the node data union with a when predicate and exhaustiveness-check with TypeScript's never.","Validate/normalize API data against the expected node schema before feeding it to the tree.","When adding new node types, update both data model and tree templates together."],"tags":["angular","cdk-tree","template","node-def"],"backgroundTag":"missing-node-definition","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}