{"record":{"id":"005af8e998a8db00","repo":"angular/components","slug":"there-can-only-be-one-default-row-without-a-when-p-005af8","errorCode":null,"errorMessage":"There can only be one default row without a when predicate function.","messagePattern":"There can only be one default row without a when predicate function\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cdk/tree/tree.ts","lineNumber":314,"sourceCode":"\n    // In certain tests, the tree might be destroyed before this is initialized\n    // in `ngAfterContentInit`.\n    this._keyManager?.destroy();\n  }\n\n  ngOnInit() {\n    this._checkTreeControlUsage();\n    this._initializeDataDiffer();\n  }\n\n  ngAfterViewInit() {\n    this._viewInit = true;\n  }\n\n  private _updateDefaultNodeDefinition() {\n    const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);\n    if (defaultNodeDefs.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw getTreeMultipleDefaultNodeDefsError();\n    }\n    this._defaultNodeDef = defaultNodeDefs[0];\n  }\n\n  /**\n   * Sets the node type for the tree, if it hasn't been set yet.\n   *\n   * This will be called by the first node that's rendered in order for the tree\n   * to determine what data transformations are required.\n   */\n  _setNodeTypeIfUnset(newType: 'flat' | 'nested') {\n    const currentType = this._nodeType.value;\n\n    if (currentType === null) {\n      this._nodeType.next(newType);\n    } else if ((typeof ngDevMode === 'undefined' || ngDevMode) && currentType !== newType) {\n      console.warn(\n        `Tree is using conflicting node types which can cause unexpected behavior. ` +","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/tree/tree.ts#L296-L332","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n<cdk-node-def *cdkNodeDef=\"let node\">Folder: {{node.name}}</cdk-node-def>\n<cdk-node-def *cdkNodeDef=\"let node\">File: {{node.name}}</cdk-node-def>\n// after\n<cdk-node-def *cdkNodeDef=\"let node; when: isFolder\">Folder: {{node.name}}</cdk-node-def>\n<cdk-node-def *cdkNodeDef=\"let node\">File: {{node.name}}</cdk-node-def>","handlingStrategy":"validation","validationCode":"// at content-init time, before rendering the tree\nconst nodeDefs = getDirectives(treeEl, CdkNodeDef) /* or inspect QueryList in custom code */;\nconst defaults = nodeDefs.filter(d => !d.when);\nif (defaults.length > 1) {\n  throw new Error('Only one node def may omit a `when` predicate');\n}","typeGuard":"interface ValidNodeDefConfig { when?: (data: any, index: number) => boolean; }\nfunction hasSingleDefault(defs: ValidNodeDefConfig[]): defs is [ValidNodeDefConfig, ...ValidNodeDefConfig[]] & { 0: ValidNodeDefConfig } {\n  return defs.filter(d => !d.when).length <= 1;\n}","tryCatchPattern":"import { getTreeMultipleDefaultNodeDefsError } from '@angular/cdk/tree';\ntry {\n  tree.ngAfterContentChecked();\n} catch (e) {\n  if ((e as Error).message.includes('one default row without a when')) {\n    console.error('Add a when predicate to all but one cdk-node-def');\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["angular-cdk","tree","template-configuration","dev-mode"],"backgroundTag":"duplicate-default-node-def","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}