mem0ai/mem0 · error · Error
Oracle filter operator '${operator}' requires a non-empty ar
Error message
Oracle filter operator '${operator}' requires a non-empty array What it means
The in/nin operators compile to a JSON_EXISTS '@ in (...)' list, which requires at least one element to form valid predicate syntax and a NOT-wrap for nin. Passing a non-array operand or an empty array is rejected up front.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/oracledb.ts:189
}
if (operand === null) {
if (operator !== "eq" && operator !== "ne") {
throw new Error(
`Oracle filter operator '${operator}' does not support null`,
);
}
predicates.push(`@ ${COMPARISON_OPERATORS[operator]} null`);
continue;
}
const [variable, passing] = bindFilterValue(operand, binds);
predicates.push(`@ ${COMPARISON_OPERATORS[operator]} ${variable}`);
passings.push(passing);
continue;
}
if (operator === "in" || operator === "nin") {
if (!Array.isArray(operand) || operand.length === 0) {
throw new Error(
`Oracle filter operator '${operator}' requires a non-empty array`,
);
}
const variables: string[] = [];
const listPassings: string[] = [];
for (const item of operand) {
if (!isScalar(item)) {
throw new Error(
`Oracle filter operator '${operator}' requires scalar values`,
);
}
if (item === null) {
variables.push("null");
continue;
}
const [variable, passing] = bindFilterValue(item, binds);
variables.push(variable);View on GitHub (pinned to 001c235229)
Solutions
- Skip the filter clause entirely when the list is empty rather than sending { in: [] }.
- Wrap single values in an array: { status: { in: ['active'] } }.
- Split strings into arrays: ids.split(',') before filtering.
- For 'match anything' semantics with nin and an empty exclusion list, omit the nin clause instead.
Example fix
// before
const filters = statuses.length ? { status: { in: statuses } } : { status: { in: [] } };
// after
const filters = statuses.length > 0 ? { status: { in: statuses } } : undefined;
await memory.search('q', { filters }); Defensive patterns
Strategy: validation
Validate before calling
function sanitizeInFilters(filters: any): any {
if (Array.isArray(filters)) return filters.map(sanitizeInFilters);
if (!filters || typeof filters !== 'object') return filters;
const out: Record<string, any> = {};
for (const [k, v] of Object.entries(filters)) {
if (v && typeof v === 'object' && ('in' in v || 'nin' in v)) {
const cleaned: Record<string, any> = {};
for (const [op, list] of Object.entries(v)) {
if ((op === 'in' || op === 'nin') && (!Array.isArray(list) || list.length === 0)) continue; // drop empty/invalid
cleaned[op] = list;
}
if (Object.keys(cleaned).length) out[k] = cleaned;
} else out[k] = v;
}
return Object.keys(out).length ? out : undefined;
} Type guard
const isNonEmptyArray = (v: unknown): v is unknown[] => Array.isArray(v) && v.length > 0;
Prevention
- Only include in/nin clauses when the list has at least one element.
- Wrap scalars into one-element arrays before passing to in.
- Treat empty allowlists as 'no filter', not { in: [] }.
When it happens
Trigger: { status: { in: [] } } (empty array, usually from dynamic list-building), { status: 'active' } where a bare string reaches the operator branch, { ids: { in: 'abc' } } (string instead of array), or { ids: { in: null } }.
Common situations: Whitelist/allowlist filters computed at runtime that end up empty (e.g. no user roles matched); passing a comma-separated string instead of an array; a client sending a scalar where the server forwards it as the in-operand.
Related errors
- Oracle filter operator '${operator}' requires scalar values
- Unsupported Oracle filter operator(s) for field '${metadataK
- Oracle filter operator '${operator}' requires a scalar value
- Oracle filter operator '${operator}' does not support null
- Oracle filter operator '${operator}' requires a string value
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/68dc84a9b097c2f5.
Report an issue: GitHub.