n8n - 💡(How to fix) Fix DataTable node: `mode: "name"` with dynamic expression value crashes with "Cannot read properties of undefined (reading 'toLowerCase')"

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

TypeError: Cannot read properties of undefined (reading 'toLowerCase') at resolveDataTableId (packages/nodes-base/nodes/DataTable/common/utils.ts:36:42)

Root Cause

Root cause (source-level)

Fix Action

Fix / Workaround

Workarounds for users

Until patched:

  • Use mode: "id" with the data table ID stored in a previous node's output
  • Use mode: "list" for design-time-known tables (no dynamic value needed)
  • Pre-resolve in upstream Code node — does NOT help if the table name is genuinely dynamic per execution (same underlying bug fires)

Forces architectures that need dynamic table lookups (multi-tenant systems with per-tenant tables — e.g. per-customer user/seat tables) to maintain redundant ID columns alongside name columns purely as a workaround. Eliminating the bug would let users reference tables by name everywhere, simplifying schemas + making them resilient to table rebuilds (rebuilds rotate IDs but keep names).

Code Example

TypeError: Cannot read properties of undefined (reading 'toLowerCase')
    at resolveDataTableId (packages/nodes-base/nodes/DataTable/common/utils.ts:36:42)

---

filter: { name: resourceLocator.value.toLowerCase() },

---

// In resolveDataTableId, name branch:
const resolved = ctx.getNodeParameter('dataTableId.value', itemIndex, '', { extractValue: true }) as string;
if (!resolved) {
  throw new NodeOperationError(ctx.getNode(), 'Data table name expression evaluated to empty value');
}
filter: { name: resolved.toLowerCase() },
RAW_BUFFERClick to expand / collapse

Bug

The n8n-nodes-base.dataTable node's dataTableId field, when configured with mode: "name" AND a dynamic expression value (anything starting with ={{), crashes at runtime with:

TypeError: Cannot read properties of undefined (reading 'toLowerCase')
    at resolveDataTableId (packages/nodes-base/nodes/DataTable/common/utils.ts:36:42)

Static literal values and expressions that resolve statically work fine. Any dynamic $-reference breaks.

Expected behaviour

Dynamic expression values should be resolved at runtime (the same way mode: "id" and mode: "list" already work after PR #23936) and the resolved string passed to the lookup.

Actual behaviour

Runtime crash. The unresolved expression descriptor is passed directly to .toLowerCase().

Reproducer (n8n 2.19.2)

The failure can be reproduced with any data table reference in name mode that uses a dynamic value:

dataTableId configResult
{ mode: "name", value: "client_subscriptions" } (literal string)✅ works
{ mode: "name", value: "={{ \"client_subscriptions\" }}" } (expression with static literal)✅ works
{ mode: "name", value: "={{ $json.user_table_name }}" } (dynamic, direct input)❌ crashes
{ mode: "name", value: "={{ $('Some Node').first().json.user_table_name }}" } (dynamic, node lookback)❌ crashes

All four value strings resolve to the same string ("client_subscriptions" or whichever) at runtime. Only the dynamic-expression variants crash.

Root cause (source-level)

At packages/nodes-base/nodes/DataTable/common/utils.ts:36:

filter: { name: resourceLocator.value.toLowerCase() },

For mode: "name", the code calls .toLowerCase() directly on resourceLocator.value with no expression resolution and no nullish guard.

The id and list branches were refactored in PR #23936 (shipped in n8n 2.3.1, Jan 2026) to use ctx.getNodeParameter(..., { extractValue: true }) which evaluates ={{ ... }} expressions correctly. The name branch was left unchanged.

When the user provides a dynamic expression, n8n hasn't resolved it before passing it to resolveDataTableId — so resourceLocator.value is effectively undefined at this call site, hence the crash. Literal-wrapped expressions like ={{ "string" }} survive because they're statically resolvable upstream.

Suggested fix

Mirror PR #23936's approach in the name branch:

// In resolveDataTableId, name branch:
const resolved = ctx.getNodeParameter('dataTableId.value', itemIndex, '', { extractValue: true }) as string;
if (!resolved) {
  throw new NodeOperationError(ctx.getNode(), 'Data table name expression evaluated to empty value');
}
filter: { name: resolved.toLowerCase() },

(Pseudocode — would need adapting to the exact function signature.)

Workarounds for users

Until patched:

  • Use mode: "id" with the data table ID stored in a previous node's output
  • Use mode: "list" for design-time-known tables (no dynamic value needed)
  • Pre-resolve in upstream Code node — does NOT help if the table name is genuinely dynamic per execution (same underlying bug fires)

Environment

  • n8n version: 2.19.2 (self-hosted via Docker)
  • Node version: per n8n container default
  • OS: Linux container

Related

  • PR #23936 — fixed list/id branches but skipped name branch
  • PR #23889 — closed/reimplemented as #23936
  • Issue #23884 — related, different symptom

Impact

Forces architectures that need dynamic table lookups (multi-tenant systems with per-tenant tables — e.g. per-customer user/seat tables) to maintain redundant ID columns alongside name columns purely as a workaround. Eliminating the bug would let users reference tables by name everywhere, simplifying schemas + making them resilient to table rebuilds (rebuilds rotate IDs but keep names).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

n8n - 💡(How to fix) Fix DataTable node: `mode: "name"` with dynamic expression value crashes with "Cannot read properties of undefined (reading 'toLowerCase')"