n8n-io/n8n · error · UnsupportedNodeError

Unsupported syntax: 'Dynamic property assignment' is not all

Error message

Unsupported syntax: 'Dynamic property assignment' is not allowed in SDK code

What it means

Thrown by visitAssignmentExpression when the left-hand property is neither a non-computed Identifier nor a Literal. This rejects computed/dynamic property keys in assignments like `obj[someVar] = value` or `obj[expr] = value`. The interpreter only allows statically-known property names for security and predictability.

Source

Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/interpreter.ts:739

		}

		const obj = this.evaluate(node.left.object);

		if (obj === null || obj === undefined) {
			throw new InterpreterError(
				`Cannot assign property on ${String(obj)}`,
				node.loc ?? undefined,
				this.sourceCode,
			);
		}

		let propName: string | number;
		if (node.left.property.type === 'Identifier' && !node.left.computed) {
			propName = node.left.property.name;
		} else if (node.left.property.type === 'Literal') {
			propName = node.left.property.value as string | number;
		} else {
			throw new UnsupportedNodeError(
				'Dynamic property assignment',
				node.left.property.loc ?? undefined,
				this.sourceCode,
			);
		}

		const value = this.evaluate(node.right);
		(obj as Record<string | number, unknown>)[propName] = value;
		return value;
	}

	/**
	 * Get set of declared variable names.
	 */
	private getVariableNames(): Set<string> {
		return new Set(this.variables.keys());
	}
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Use static dot notation: `obj.fixedName = value`.
  2. Use a string-literal key in brackets: `obj['fixedKey'] = value` (Literal is allowed).
  3. Build the object in one shot with an object literal instead of mutating dynamic keys: `const obj = { [computedKey]: value }` — but note computed keys in literals are also restricted; prefer a fixed structure or move dynamic logic to a Code node.

Example fix

// before
const key = dynamicKey();
obj[key] = value;

// after
obj.fixedKey = value;
// or, if the key is a known constant string:
obj['fixedKey'] = value;
Defensive patterns

Strategy: validation

Validate before calling

import { parseSDKCode } from '@n8n/workflow-sdk/ast-interpreter/parser';

function findDynamicAssignmentKeys(code: string): string[] {
  const issues: string[] = [];
  const ast = parseSDKCode(code);
  JSON.stringify(ast, (k, v) => {
    if (v?.type === 'AssignmentExpression' && v.left?.type === 'MemberExpression' && v.left.computed) {
      if (v.left.property?.type !== 'Literal') {
        issues.push(`Dynamic assignment key at line ${v.loc?.start.line}: use a static name or literal`);
      }
    }
    return v;
  });
  return issues;
}

Type guard

function isStaticKey(prop: unknown): boolean {
  if (!prop || typeof prop !== 'object') return false;
  const t = (prop as { type?: string }).type;
  return t === 'Identifier' || t === 'Literal';
}

Try / catch

import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';
import { UnsupportedNodeError } from '@n8n/workflow-sdk/ast-interpreter/errors';

try {
  interpretSDKCode(code, sdkFunctions);
} catch (e) {
  if (e instanceof UnsupportedNodeError && /Dynamic property assignment/.test(e.message)) {
    // instruct user to replace obj[var] = v with obj.fixedKey = v
  }
  throw e;
}

Prevention

When it happens

Trigger: SDK code containing `obj[variableName] = value`, `obj[computeKey()] = value`, or any bracket-notation assignment where the key is not a string/number literal. Template-literal keys (`obj[`key`] = value`) also fail because TemplateLiteral is not a Literal.

Common situations: Pasting generic JavaScript that builds objects dynamically; code generators that emit bracket-notation updates; refactoring from a loop into SDK code without flattening.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/3d8cb4002baae530. Report an issue: GitHub.