n8n-io/n8n · error · Error
Filter operator "${operator}" on key "${key}" requires a str
Error message
Filter operator "${operator}" on key "${key}" requires a string, number, or boolean value. What it means
For the scalar operators 'eq' and 'ne', assertValidCondition requires the value to be a string, number, or boolean. Arrays, objects, null, and undefined are rejected because scalar equality against non-scalars has no consistent meaning across vector store backends. This is the final fallthrough check after the in/nin branch returns.
Source
Thrown at packages/@n8n/agents/src/sdk/vector-store-filter.ts:64
}
if (operator === 'in' || operator === 'nin') {
if (!Array.isArray(value) || value.length === 0) {
throw new Error(
`Filter operator "${operator}" on key "${key}" requires a non-empty array value.`,
);
}
if (value.some((v) => typeof v !== 'string' && typeof v !== 'number')) {
throw new Error(
`Filter operator "${operator}" on key "${key}" requires array elements to be strings or numbers.`,
);
}
return;
}
// eq, ne
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
throw new Error(
`Filter operator "${operator}" on key "${key}" requires a string, number, or boolean value.`,
);
}
}
function isNonEmptyArray(arr: string[]): arr is [string, ...string[]] {
return arr.length > 0;
}
/** Builds the zod schema for the model-facing `filter` tool input, scoped to `keys` (key -> description). */
export function buildFilterInputSchema(keys: Record<string, string>) {
const keyNames = Object.keys(keys);
if (!isNonEmptyArray(keyNames)) {
throw new Error('filterableKeys must contain at least one key');
}
const keyDescriptions = keyNames.map((key) => `- ${key}: ${keys[key]}`).join('\n');
View on GitHub (pinned to 5ac6606e81)
Solutions
- Pass a single primitive: value: 'x', value: 42, or value: true for 'eq'/'ne'.
- If you have an array, switch the operator to 'in'/'nin' instead of 'eq' with an array value.
- Reduce objects to their scalar key before building the condition: value: obj.id.
Example fix
// before
store.search('q', {
filter: { conditions: [{ key: 'tag', operator: 'eq', value: ['x'] }], combineWith: 'and' },
}); // throws
// after — single scalar
store.search('q', {
filter: { conditions: [{ key: 'tag', operator: 'eq', value: 'x' }], combineWith: 'and' },
}); Defensive patterns
Strategy: type-guard
Validate before calling
function eqCondition(key: string, value: unknown) {
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
throw new Error(`'eq' filter on ${key} requires a string, number, or boolean`);
}
return { key, operator: 'eq' as const, value };
} Type guard
function isScalarValue(v: unknown): v is string | number | boolean {
return typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';
} Prevention
- Use 'eq'/'ne' only with single primitive values; switch to 'in' for sets.
- Reduce objects to their scalar key before building a scalar condition.
- Guard optional/null fields before constructing eq conditions.
When it happens
Trigger: Calling search with filter: { conditions: [{ key: 'tag', operator: 'eq', value: ['x'] }] } (array for scalar op), value: { id: 1 } (object), or value: null. Also hit by value: undefined when a field is missing.
Common situations: Wrapping a single value in an array by mistake; passing an object that should be reduced to one of its scalar fields; null leaking from optional form fields; using 'eq' where 'in' was intended for a set.
Related errors
- Filter operator "${operator}" on key "${key}" requires array
- Filter operator "${operator}" on key "${key}" requires all a
- Invalid filter operator "${operator}" for key "${key}". Supp
- Filter operator "${operator}" on key "${key}" requires a non
- filterableKeys must contain at least one key
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/c64908eecba9a73a.
Report an issue: GitHub.