element-plus/element-plus · error · Error
For nested data item, row-key is required.
Error message
For nested data item, row-key is required.
What it means
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.
Source
Thrown at packages/components/table/src/table-body/render-helper.ts:257
const tmp = [rowRender(row, $index, treeRowData ?? undefined)]
// 渲染嵌套数据
if (cur) {
// currentRow 记录的是 index,所以还需主动增加 TreeTable 的 index
let i = 0
const traverse = (children: T[], parent: TreeData) => {
if (!(children && children.length && parent)) return
children.forEach((node) => {
// 父节点的 display 状态影响子节点的显示状态
const innerTreeRowData: Partial<Record<string, any>> = {
display: parent.display && parent.expanded,
level: parent.level! + 1,
expanded: false,
noLazyChildren: false,
loading: false,
}
const childKey = getRowIdentity(node, rowKey.value)
if (isPropAbsent(childKey)) {
throw new Error('For nested data item, row-key is required.')
}
cur = { ...treeData.value[childKey] }
// 对于当前节点,分成有无子节点两种情况。
// 如果包含子节点的,设置 expanded 属性。
// 对于它子节点的 display 属性由它本身的 expanded 与 display 共同决定。
if (cur) {
innerTreeRowData.expanded = cur.expanded
// 懒加载的某些节点,level 未知
cur.level = cur.level || innerTreeRowData.level
cur.display = !!(cur.expanded && innerTreeRowData.display)
if (isBoolean(cur.lazy)) {
if (isBoolean(cur.loaded) && cur.loaded) {
innerTreeRowData.noLazyChildren = !(
cur.children && cur.children.length
)
}
innerTreeRowData.loading = cur.loading
}View on GitHub (pinned to d357b66546)
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
Example fix
// before <el-table :data="treeRows"> // after <el-table :data="treeRows" row-key="id">
Defensive patterns
Strategy: validation
Validate before calling
function validateNestedRows(rows: any[], rowKey?: string) {
if (!rowKey) throw new Error('row-key is required for nested data')
const walk = (list: any[]) => list.forEach(r => {
if (r[rowKey] == null) throw new Error(`Row missing row-key field '${rowKey}'`)
if (Array.isArray(r.children)) walk(r.children)
})
walk(rows)
}
validateNestedRows(treeRows, 'id') Type guard
const hasIdentity = (r: any, k: string): r is { [k: string]: string | number } => r[k] != null Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- [ElTable]children must be an empty array.
- [ElTable] data must be an array
- [Table] rowKey is required in updateKeyChild
- [ElTable] prop row-key is required
- Can not find table layout.
AI-assisted analysis of element-plus/element-plus@d357b66546 (2026-08-29).
Data as JSON: /api/errors/8c1d344920a32a4f.
Report an issue: GitHub.