n8n-io/n8n · error · SecurityError
Dynamic property access is not allowed. Use static property
Error message
Dynamic property access is not allowed. Use static property names.
What it means
Thrown by validateMemberExpression when a member access is computed (`obj[expr]`) AND the expression is not a Literal. Dynamic/computed property access with a non-literal key is blocked because the interpreter cannot statically verify it is safe. Literal keys like `obj['key']` or `arr[0]` are allowed; variable keys like `obj[name]` are not. The SecurityError is constructed with a custom detail message.
Source
Thrown at packages/@n8n/workflow-sdk/src/ast-interpreter/validators.ts:328
if (node.callee.type === 'MemberExpression') {
const memberExpr = node.callee;
if (memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'constructor') {
throw new SecurityError('constructor access', node.loc ?? undefined, sourceCode);
}
}
}
/**
* Validate a member expression.
* @throws SecurityError if the access is dangerous
*/
export function validateMemberExpression(node: MemberExpression, sourceCode: string): void {
// Reject dynamic property access obj[expr] (computed access)
// Allow obj.property (non-computed)
if (node.computed) {
// Allow simple literal keys like obj["key"] or obj[0]
if (node.property.type !== 'Literal') {
throw new SecurityError(
'computed-member-access',
node.loc ?? undefined,
sourceCode,
'Dynamic property access is not allowed. Use static property names.',
);
}
}
// Check for dangerous property names (both dot notation and literal keys)
const propName =
node.property.type === 'Identifier'
? node.property.name
: node.property.type === 'Literal' && typeof node.property.value === 'string'
? node.property.value
: undefined;
if (
propName !== undefined &&View on GitHub (pinned to 5ac6606e81)
Solutions
- Replace dynamic key access with a static property name: `obj.fixedKey`.
- If the key is a known constant, use a literal: `obj['fixedKey']` or `arr[0]`.
- Refactor dynamic lookup into a conditional or a fixed map defined as an object literal with all keys spelled out.
- Move genuinely dynamic lookups to a Code node where computed access is permitted.
Example fix
// before const key = 'dynamic' + suffix; const val = obj[key]; // after const val = obj.fixedDynamicSuffix; // static name // or, if the key is a fixed string: const val = obj['fixedKey'];
Defensive patterns
Strategy: validation
Validate before calling
import { parseSDKCode } from '@n8n/workflow-sdk/ast-interpreter/parser';
function findComputedNonLiteralAccess(code: string): string[] {
const issues: string[] = [];
const ast = parseSDKCode(code);
JSON.stringify(ast, (k, v) => {
if (v?.type === 'MemberExpression' && v.computed && v.property?.type !== 'Literal') {
issues.push(`Computed non-literal access at line ${v.loc?.start.line}: use a static name or literal key`);
}
return v;
});
return issues;
} Type guard
function isLiteralKey(memberNode: { computed: boolean; property: { type?: string } }): boolean {
return !memberNode.computed || memberNode.property.type === 'Literal';
} Try / catch
import { interpretSDKCode } from '@n8n/workflow-sdk/ast-interpreter/interpreter';
import { SecurityError } from '@n8n/workflow-sdk/ast-interpreter/errors';
try {
interpretSDKCode(code, sdkFunctions);
} catch (e) {
if (e instanceof SecurityError && e.pattern === 'computed-member-access') {
// instruct: replace obj[var] with obj.fixedKey or obj['literal']
}
throw e;
} Prevention
- Ban computed member access in builder code via lint; require dot notation or literal keys.
- Use `obj['fixedKey']` or `arr[0]` when a bracket is needed — both are allowed.
- Move dictionary-style lookups to a Code node.
When it happens
Trigger: SDK code containing `obj[variableName]`, `arr[i]` where `i` is not a numeric literal, `obj[someExpression]`, or `map[key]` with a computed non-literal key. Reading OR writing — validateMemberExpression runs for both.
Common situations: Dynamic lookups in configuration objects; indexed access in what was a loop; using a variable to select a property; porting dictionary-lookup code.
Related errors
- Security violation: '${name}' is not allowed
- Security violation: 'eval()' is not allowed
- Security violation: 'Function()' is not allowed
- Security violation: 'require()' is not allowed
- Security violation: 'constructor access' is not allowed
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/f3847e97d1024cd0.
Report an issue: GitHub.