n8n-io/n8n · error · Error

MCP server "${this.config.name}": connectionTimeoutMs must b

Error message

MCP server "${this.config.name}": connectionTimeoutMs must be a positive finite number

What it means

Thrown by the Set node validator (v3.3+) when an assignment object is missing a non-empty id, name, or type field. Each of those three keys must be a non-empty trimmed string; whitespace-only values are treated as missing.

Source

Thrown at packages/@n8n/agents/src/runtime/mcp/mcp-connection.ts:128

		this.connectionPromise = this.connectWithTransport(this.createTransport(this.config, sdk));
		try {
			await this.connectionPromise;
		} catch (error) {
			this.connectionPromise = undefined;
			throw error;
		}
	}

	private async connectWithTransport(transport: McpTransport): Promise<void> {
		if (!this.client) throw new Error('MCP client not initialized; connect() must be called first');
		const client = this.client;
		const timeoutMs = this.config.connectionTimeoutMs;
		if (timeoutMs === undefined) {
			await client.connect(transport);
			return;
		}
		if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
			throw new Error(
				`MCP server "${this.config.name}": connectionTimeoutMs must be a positive finite number`,
			);
		}
		let timeoutId: ReturnType<typeof setTimeout> | undefined;
		try {
			await Promise.race([
				client.connect(transport),
				new Promise<never>((_, reject) => {
					timeoutId = setTimeout(() => {
						reject(
							new Error(
								`MCP server "${this.config.name}": connection timed out after ${timeoutMs}ms`,
							),
						);
					}, timeoutMs);
				}),
			]);
		} catch (error) {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Provide a non-empty id (uuid or incrementing id) for every assignment.
  2. Provide a non-empty name (the output field name) and a non-empty type (e.g. 'string', 'number', 'boolean').
  3. Strip accidental whitespace from these fields.

Example fix

// before — missing id and type
assignments: { assignments: [{ name: 'status', value: 'ok' }] }

// after
assignments: {
  assignments: [{ id: '1', name: 'status', value: 'ok', type: 'string' }],
}
Defensive patterns

Strategy: validation

Validate before calling

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim() !== '';
}

function validateAssignmentKeys(a: Record<string, unknown>): string[] {
  return (['id', 'name', 'type'] as const).filter((k) => !isNonEmptyString(a[k]));
}

const missing = validateAssignmentKeys(assignment);
if (missing.length) throw new Error(`Assignment missing: ${missing.join(', ')}`);

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim() !== '';
}

Prevention

When it happens

Trigger: For a record assignment, the validator iterates keys ['id','name','type'] and fires one issue per key where !isNonEmptyString(assignment[key]). Reported at parameterPath parameters.assignments.assignments[index].<key>.

Common situations: Forgetting the id (which v3.3 requires); leaving type blank; an AI builder omits type assuming it is inferred; whitespace copied from a template.

Understand the failure class

Related errors


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