n8n-io/n8n · error · NodeOperationError
Error: No JSON string provided.
Error message
Error: No JSON string provided.
What it means
NodeOperationError thrown by `getFilterValue` when the option `name` is truthy but its value is not a string. The handler only attempts `JSON.parse` on strings, so any other type (number, object, array) — which the UI should not produce but expressions can — lands here.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/VectorStoreMongoDBAtlas.node.ts:256
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') {
try {
return JSON.parse(options[name]);
} catch (error) {
throw new NodeOperationError(context.getNode(), `Error: ${error.message}`, {
itemIndex,
description: `Could not parse JSON for ${name}`,
});
}
}
throw new NodeOperationError(context.getNode(), 'Error: No JSON string provided.', {
itemIndex,
description: `Could not parse JSON for ${name}`,
});
}
return undefined;
}
class ExtendedMongoDBAtlasVectorSearch extends MongoDBAtlasVectorSearch {
mongoClient: MongoClient;
preFilter: IDataObject;
postFilterPipeline?: IDataObject[];
constructor(
embeddings: EmbeddingsInterface,
options: MongoDBAtlasVectorSearchLibArgs,
mongoClient: MongoClient,
preFilter: IDataObject,View on GitHub (pinned to 5ac6606e81)
Solutions
- If the value is already an object, pass it through `JSON.stringify` first or restructure to bypass the option field.
- Set the option field to a JSON string literal (e.g. `{ "category": "books" }`).
- Use an expression that returns a string: `={{ JSON.stringify($json.filter) }}`.
Example fix
// before
if (typeof options[name] === 'string') {
// ... JSON.parse ...
}
throw new NodeOperationError(context.getNode(), 'Error: No JSON string provided.', {
itemIndex,
description: `Could not parse JSON for ${name}`,
});
// after: accept already-parsed objects instead of rejecting them
if (typeof options[name] === 'string') {
try { return JSON.parse(options[name]); } catch (error) { /* ... */ }
}
if (options[name] && typeof options[name] === 'object') {
return options[name];
}
throw new NodeOperationError(context.getNode(), `Expected a JSON string for ${name}`, { itemIndex }); Defensive patterns
Strategy: type-guard
Validate before calling
// Accept either a JSON string or an already-parsed object.
function resolveFilterValue<T>(value: unknown, name: string, itemIndex: number): T | undefined {
if (!value) return undefined;
if (typeof value === 'string') {
try { return JSON.parse(value) as T; }
catch (error) { throw new NodeOperationError(/* ... */); }
}
if (typeof value === 'object') return value as T;
throw new NodeOperationError(/* 'Expected JSON string or object' */);
} Type guard
function isJsonable(value: unknown): value is string | object {
return typeof value === 'string' || (typeof value === 'object' && value !== null);
} Try / catch
// No external try/catch needed; this is a synchronous shape check.
if (options[name] && typeof options[name] !== 'string' && typeof options[name] === 'object') {
return options[name];
}
if (typeof options[name] === 'string') { /* JSON.parse path */ }
throw new NodeOperationError(context.getNode(), `Expected a JSON string for ${name}`, { itemIndex }); Prevention
- Pass already-parsed objects via expressions and adjust the helper to accept them.
- Document that the field accepts strict JSON strings only by default.
- Add a unit test covering string, object, and missing inputs.
When it happens
Trigger: An expression bound to the pre/post filter option returns an object directly (e.g. `={{ $json.filter }}` where `filter` is already an object) instead of a JSON string; the option value was injected programmatically as a non-string.
Common situations: User passes an already-parsed object via expression and skips the JSON-string step the field expects; programmatic workflow injection setting the option to an object; typeVersion drift leaving the option as a non-string.
Related errors
- Parameter ${key} must be a string
- Collection must be a string
- Error: ${error.message}
- Index ${mongoVectorIndexName} not found
- Error connecting to ChromaDB: ${message}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/d31c6872dbb9c4e7.
Report an issue: GitHub.