{"record":{"id":"8c1d344920a32a4f","repo":"element-plus/element-plus","slug":"for-nested-data-item-row-key-is-required","errorCode":null,"errorMessage":"For nested data item, row-key is required.","messagePattern":"For nested data item, row-key is required\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/table/src/table-body/render-helper.ts","lineNumber":257,"sourceCode":"      const tmp = [rowRender(row, $index, treeRowData ?? undefined)]\n      // 渲染嵌套数据\n      if (cur) {\n        // currentRow 记录的是 index，所以还需主动增加 TreeTable 的 index\n        let i = 0\n        const traverse = (children: T[], parent: TreeData) => {\n          if (!(children && children.length && parent)) return\n          children.forEach((node) => {\n            // 父节点的 display 状态影响子节点的显示状态\n            const innerTreeRowData: Partial<Record<string, any>> = {\n              display: parent.display && parent.expanded,\n              level: parent.level! + 1,\n              expanded: false,\n              noLazyChildren: false,\n              loading: false,\n            }\n            const childKey = getRowIdentity(node, rowKey.value)\n            if (isPropAbsent(childKey)) {\n              throw new Error('For nested data item, row-key is required.')\n            }\n            cur = { ...treeData.value[childKey] }\n            // 对于当前节点，分成有无子节点两种情况。\n            // 如果包含子节点的，设置 expanded 属性。\n            // 对于它子节点的 display 属性由它本身的 expanded 与 display 共同决定。\n            if (cur) {\n              innerTreeRowData.expanded = cur.expanded\n              // 懒加载的某些节点，level 未知\n              cur.level = cur.level || innerTreeRowData.level\n              cur.display = !!(cur.expanded && innerTreeRowData.display)\n              if (isBoolean(cur.lazy)) {\n                if (isBoolean(cur.loaded) && cur.loaded) {\n                  innerTreeRowData.noLazyChildren = !(\n                    cur.children && cur.children.length\n                  )\n                }\n                innerTreeRowData.loading = cur.loading\n              }","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/element-plus/element-plus/blob/d357b665467f48639265328b714ed3e9255f1fb0/packages/components/table/src/table-body/render-helper.ts#L239-L275","documentation":"When rendering nested (tree) rows, the body renderer computes each child row's key via getRowIdentity(node, rowKey). If a nested data item has no usable identity because row-key is missing or the keyed field is absent on that row, it throws. Tree rendering cannot track expansion/display state without stable keys.","triggerScenarios":"Passing nested data (rows with children arrays) to el-table without row-key prop; row-key pointing to a field that is undefined on some nested child rows; rows whose identity field holds null/undefined values.","commonSituations":"Tree data from an API where only some levels include the id field; adding children to data after the table was built for flat rows without row-key; row-key bound to a getter-unfriendly field name (case mismatch).","solutions":["Add row-key=\"id\" (or equivalent) to el-table when data is nested","Ensure every nested child row has a defined, unique value for the row-key field","Normalize API data to inject ids before assigning to :data"],"exampleFix":"// before\n<el-table :data=\"treeRows\">\n// after\n<el-table :data=\"treeRows\" row-key=\"id\">","handlingStrategy":"validation","validationCode":"function validateNestedRows(rows: any[], rowKey?: string) {\n  if (!rowKey) throw new Error('row-key is required for nested data')\n  const walk = (list: any[]) => list.forEach(r => {\n    if (r[rowKey] == null) throw new Error(`Row missing row-key field '${rowKey}'`)\n    if (Array.isArray(r.children)) walk(r.children)\n  })\n  walk(rows)\n}\nvalidateNestedRows(treeRows, 'id')","typeGuard":"const hasIdentity = (r: any, k: string): r is { [k: string]: string | number } => r[k] != null","tryCatchPattern":null,"preventionTips":["Require row-key whenever :data contains children arrays","Normalize API data so nested children always carry the keyed id","Add a data-shape assertion before binding tree data to el-table"],"tags":["element-plus","table","tree","row-key","rendering"],"backgroundTag":"row-key-required","analyzedSha":"d357b665467f48639265328b714ed3e9255f1fb0","analyzedAt":"2026-08-29T08:59:07.682Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}