TanStack/table · warning

"${key}" in deeply nested key "${accessorKey}" returned unde

Error message

"${key}" in deeply nested key "${accessorKey}" returned undefined.

What it means

When resolving an accessorKey with dot notation (e.g. 'user.address.city'), constructColumn walks each key segment against the row object. If any intermediate key resolves to undefined, it logs this warning in development, indicating the accessor path does not match the actual row data shape.

Source

Thrown at packages/table-core/src/core/columns/constructColumn.ts:78

      ? resolvedColumnDef.header
      : undefined)

  let accessorFn: AccessorFn<TData, TValue> | undefined

  if (resolvedColumnDef.accessorFn) {
    accessorFn = resolvedColumnDef.accessorFn
  } else if (accessorKey !== undefined) {
    // Support deep accessor keys
    if (typeof accessorKey === 'string' && accessorKey.includes('.')) {
      const keys = accessorKey.split('.')
      accessorFn = (originalRow: TData) => {
        let result = originalRow as Record<string, any> | undefined

        for (let i = 0; i < keys.length; i++) {
          const key = keys[i]!
          result = result?.[key]
          if (process.env.NODE_ENV === 'development' && result === undefined) {
            console.warn(
              `"${key}" in deeply nested key "${accessorKey}" returned undefined.`,
            )
          }
        }

        return result as TValue
      }
    } else {
      accessorFn = (originalRow: TData) =>
        (originalRow as any)[resolvedColumnDef.accessorKey]
    }
  }

  if (!id) {
    if (process.env.NODE_ENV === 'development') {
      throw new Error(
        resolvedColumnDef.accessorFn
          ? `coreColumnsFeature require an id when using an accessorFn`

View on GitHub (pinned to d01c01bedb)

Solutions

  1. Fix the accessorKey string so each dot-separated segment matches the row data exactly.
  2. Log one row of your data and confirm the nested path exists on every record.
  3. If rows legitimately lack the nested value, supply an accessorFn: row => row?.user?.address?.city ?? '' instead of accessorKey.
  4. Normalize/transform API data so the nested structure matches the column definition.

Example fix

// before
{ accessorKey: 'usr.profile.name', header: 'Name' }

// after
{ accessorKey: 'user.profile.name', header: 'Name' }
// or for nullable data:
{ id: 'name', accessorFn: (row) => row?.user?.profile?.name ?? '', header: 'Name' }
Defensive patterns

Strategy: validation

Validate before calling

function validateAccessorKey(data: any[], accessorKey: string): boolean {
  return data.every((row) =>
    accessorKey.split('.').reduce<any>((o, k) => (o == null ? undefined : o[k]), row) !== undefined
  )
}

Type guard

function hasPath<T, P extends string>(row: T, path: P): boolean {
  return path.split('.').reduce<any>((o, k) => (o == null ? undefined : o[k]), row) !== undefined
}

Prevention

When it happens

Trigger: Defining a column with accessorKey: 'a.b.c' where a row is missing property 'a' or 'b', or a typo like accessorKey: 'usr.name' when the data uses 'user.name'; rows where a nested object is null/undefined for some records.

Common situations: Backend API changes the JSON shape; inconsistent rows (some missing nested objects); typos in accessorKey; using dot notation against data that stores keys containing literal dots.

Related errors


AI-assisted analysis of TanStack/table@d01c01bedb (2026-08-28). Data as JSON: /api/errors/42b5718e1b3122c8. Report an issue: GitHub.