n8n-io/n8n · error · NodeOperationError

Parameter ${key} must be a string

Error message

Parameter ${key} must be a string

What it means

Type-validation NodeOperationError from the `getParameter` helper used by the MongoDB Atlas node. After extracting the parameter with `extractValue: true` and casting to `string`, it re-checks at runtime that the value is actually a string. The bound callers (`getCollectionName`, `getVectorIndexName`, `getEmbeddingFieldName`, `getMetadataFieldName`) all rely on this guard.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/VectorStoreMongoDBAtlas.node.ts:228

		throw new NodeOperationError(this.getNode(), `Error: ${error.message}`);
	} finally {
		void client.close().catch(() => {});
	}
}

/**
 * Get a parameter from the context.
 * @param key - The key of the parameter.
 * @param context - The context.
 * @param itemIndex - The index.
 * @returns The value.
 */
export function getParameter(key: string, context: IFunctionsContext, itemIndex: number): string {
	const value = context.getNodeParameter(key, itemIndex, '', {
		extractValue: true,
	}) as string;
	if (typeof value !== 'string') {
		throw new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`);
	}
	return value;
}

export const getCollectionName = getParameter.bind(null, MONGODB_COLLECTION_NAME);
export const getVectorIndexName = getParameter.bind(null, VECTOR_INDEX_NAME);
export const getEmbeddingFieldName = getParameter.bind(null, EMBEDDING_NAME);
export const getMetadataFieldName = getParameter.bind(null, METADATA_FIELD_NAME);

export function getFilterValue<T>(
	name: string,
	context: IExecuteFunctions | ISupplyDataFunctions,
	itemIndex: number,
): T | undefined {
	const options: IDataObject = context.getNodeParameter('options', itemIndex, {});

	if (options[name]) {
		if (typeof options[name] === 'string') {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Open the node and set the offending field to a literal string or a string-returning expression.
  2. If using an expression, coerce to string: `={{ String($json.field) }}`.
  3. Upgrade the node typeVersion so parameter extraction matches the current contract.
  4. Inspect the saved workflow JSON for the named field and correct its value type.

Example fix

// before
export function getParameter(key: string, context: IFunctionsContext, itemIndex: number): string {
  const value = context.getNodeParameter(key, itemIndex, '', { extractValue: true }) as string;
  if (typeof value !== 'string') {
    throw new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`);
  }
  return value;
}

// after: include the received type and value in the message for fast diagnosis
if (typeof value !== 'string') {
  throw new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`, {
    itemIndex,
    description: `Received ${typeof value}: ${JSON.stringify(value)}`,
  });
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Centralize string-parameter resolution and coerce common envelopes.
function getStringParam(context: IFunctionsContext, key: string, itemIndex: number): string {
  const raw = context.getNodeParameter(key, itemIndex, '', { extractValue: true });
  if (typeof raw === 'string') return raw;
  if (raw && typeof raw === 'object' && typeof (raw as { value?: unknown }).value === 'string') {
    return (raw as { value: string }).value;
  }
  throw new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`, {
    itemIndex, description: `Received ${typeof raw}: ${JSON.stringify(raw)}`,
  });
}

Type guard

function isNonEmptyString(value: unknown): value is string {
  return typeof value === 'string' && value.length > 0;
}

Try / catch

const value = context.getNodeParameter(key, itemIndex, '', { extractValue: true });
if (!isNonEmptyString(value)) {
  throw new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`, { itemIndex });
}

Prevention

When it happens

Trigger: Any of the four bound parameters (collection name, vector index name, embedding field, metadata field) holds a non-string value at execution time — an expression returned an object/number, or the workflow JSON stored an object envelope that `extractValue` did not unwrap.

Common situations: Expression `={{ $json.someObject }}` bound to a field that should be a string; workflow migrated from a node typeVersion where the parameter shape differed; field left as the RLC envelope object.

Related errors


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