n8n-io/n8n · error
Filter operator "${operator}" on key "${key}" requires a non
Error message
Filter operator "${operator}" on key "${key}" requires a non-empty array value. What it means
Thrown by assertNonEmptyArray in the Pinecone backend when an `in` or `nin` filter condition has a value that is not an array or is an empty array. An empty `$in`/`$nin` is either a no-op or unsatisfiable, so the backend rejects it before building the Pinecone filter. The operator and key are named in the message.
Source
Thrown at packages/@n8n/agents/src/vector-stores/pinecone.ts:219
return { $or: [{ [key]: { $ne: value } }, { [key]: { $exists: false } }] };
case 'in':
assertNonEmptyArray(operator, key, value);
return { [key]: { $in: value } };
case 'nin':
assertNonEmptyArray(operator, key, value);
return { $or: [{ [key]: { $nin: value } }, { [key]: { $exists: false } }] };
default:
throw new Error(`Unsupported filter operator: "${String(operator)}"`);
}
}
function assertNonEmptyArray(
operator: string,
key: string,
value: unknown,
): asserts value is Array<string | number> {
if (!Array.isArray(value) || value.length === 0) {
throw new Error(
`Filter operator "${operator}" on key "${key}" requires a non-empty array value.`,
);
}
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Omit the `in`/`nin` condition entirely when the candidate list is empty (drop the condition from `conditions`).
- Guard filter construction: only push an `in` condition when `values.length > 0`.
- If the whole filter becomes empty, pass no filter so the store does an unfiltered query.
Example fix
// before
await store.search('q', {
filter: { conditions: [{ key: 'topic', operator: 'in', value: [] }] },
});
// after — only add the condition when non-empty
const conditions = [];
if (topics.length > 0) {
conditions.push({ key: 'topic', operator: 'in', value: topics });
}
await store.search('q',
conditions.length ? { filter: { conditions, combineWith: 'and' } } : undefined,
); Defensive patterns
Strategy: validation
Validate before calling
function dropEmptyInConditions(filter: VectorFilter): VectorFilter | undefined {
const conditions = filter.conditions.filter(
(c) => !(c.operator === 'in' || c.operator === 'nin') || (Array.isArray(c.value) && c.value.length > 0),
);
return conditions.length > 0 ? { ...filter, conditions } : undefined;
}
const f = dropEmptyInConditions(inputFilter);
await store.search('q', f ? { filter: f } : undefined); Type guard
function isInCondition(c: FilterCondition): c is FilterCondition & { operator: 'in' | 'nin'; value: (string | number)[] } {
return (c.operator === 'in' || c.operator === 'nin') && Array.isArray(c.value) && c.value.length > 0;
} Prevention
- Never push an `in`/`nin` condition unless the candidate array is non-empty.
- After building conditions, filter out empty-array in/nin entries before passing the filter.
- Treat 'all options cleared' in a UI as 'no filter', not 'empty in'.
When it happens
Trigger: Calling search with `{ filter: { conditions: [{ key: 'topic', operator: 'in', value: [] }] } }`; passing `value: undefined` or a scalar to an `in` condition; building a filter from a list that was filtered down to nothing.
Common situations: User selects zero filter values in a UI but the filter is still sent; a query builder that defaults to `[]`; deduplication/removal leaving an empty candidate list; programmatically building conditions without checking length.
Related errors
- Invalid filter operator "${operator}" for key "${key}". Supp
- Filter operator "${operator}" on key "${key}" requires a non
- Filter operator "${operator}" on key "${key}" requires array
- Filter operator "${operator}" on key "${key}" requires a str
- filterableKeys must contain at least one key
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/1c724e802e34b721.
Report an issue: GitHub.