mem0ai/mem0 · error · Error
Oracle filter groups must be non-empty objects
Error message
Oracle filter groups must be non-empty objects
What it means
buildFilterGroup requires a non-empty filter object so it can emit at least one SQL clause; Object.entries(filters ?? {}) returning zero entries means there is nothing to translate. Note that undefined/null filters never reach here (buildWhereClause short-circuits them) — only an explicitly empty object {} or an empty nested group triggers it.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/oracledb.ts:253
passings.push(passing);
}
}
const clauses = [...additionalClauses];
if (predicates.length > 0) {
clauses.unshift(jsonExists(path, predicates.join(" && "), passings));
}
return clauses.length === 1 ? clauses[0] : `(${clauses.join(" AND ")})`;
}
export function buildFilterGroup(
filters: Record<string, any>,
binds: Record<string, any>,
): string {
const entries = Object.entries(filters ?? {});
if (entries.length === 0) {
throw new Error("Oracle filter groups must be non-empty objects");
}
const clauses: string[] = [];
for (const [key, value] of entries) {
const logicalOperator = LOGICAL_OPERATORS[key];
if (logicalOperator) {
if (!Array.isArray(value) || value.length === 0) {
throw new Error(
`Logical filter operator '${key}' requires a non-empty array`,
);
}
const nested = value.map((condition) =>
buildFilterGroup(condition, binds),
);
if (logicalOperator === "not") {
clauses.push(`NOT (${nested.join(" OR ")})`);
} else {
clauses.push(View on GitHub (pinned to 001c235229)
Solutions
- Pass undefined (or omit the filters key) instead of an empty object when no filtering is needed.
- In filter-composition helpers, return undefined when the resulting object has no keys.
- Validate and drop empty nested groups: { $and: parts.filter(p => Object.keys(p).length > 0) }.
- Add an application-level check before search(): if (!Object.keys(filters).length) filters = undefined.
Example fix
// before
await memory.search('q', { filters: {} });
// after
const filters = Object.keys(built).length ? built : undefined;
await memory.search('q', { filters }); Defensive patterns
Strategy: validation
Validate before calling
function dropEmptyGroups(filters: any): any {
if (Array.isArray(filters)) {
const nested = filters.map(dropEmptyGroups).filter((f) => f !== undefined);
return nested; // caller decides whether the array is still non-empty
}
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' && !Array.isArray(v) && Object.keys(v).length === 0) continue;
out[k] = dropEmptyGroups(v);
}
return Object.keys(out).length ? out : undefined;
} Type guard
const isNonEmptyFilterObject = (v: unknown): v is Record<string, unknown> => !!v && typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length > 0;
Prevention
- Pass undefined instead of {} when no filters apply.
- Compose filters with helpers that return undefined for empty results.
- Strip empty nested groups before search().
When it happens
Trigger: search('q', { filters: {} }); or a nested group like { $and: [{}] } where an inner condition object is empty; also { $or: [] } style inputs filtered down to an empty object by upstream code.
Common situations: Dynamically composing filters where every optional key was omitted, leaving {}; spreading optional params into a base object that stays empty; forwarding a client's {} query parameter verbatim.
Related errors
- 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 non-empty ar
- Oracle filter operator '${operator}' requires scalar values
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/bd1e99102bbc1f8a.
Report an issue: GitHub.