mem0ai/mem0 · error · Error
Operator filter for field '${metadataKey}' must not be empty
Error message
Operator filter for field '${metadataKey}' must not be empty What it means
When a filter field value is an operator object, Object.entries(value) drives clause generation; an empty object has no operators to apply, so the resulting SQL predicate would be undefined (or accidentally always-true). The compiler throws to make the no-op filter explicit instead of producing surprising results.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/oracledb.ts:147
}
if (isScalar(value)) {
if (value === null) {
return jsonExists(path, "@ == null", []);
}
const [variable, passing] = bindFilterValue(value, binds);
return jsonExists(path, `@ == ${variable}`, [passing]);
}
if (Array.isArray(value)) {
throw new Error(
`Oracle filter for field '${metadataKey}' must be a scalar or an operator object`,
);
}
const operators = Object.entries(value);
if (operators.length === 0) {
throw new Error(
`Operator filter for field '${metadataKey}' must not be empty`,
);
}
const unsupported = operators
.map(([op]) => op)
.filter((op) => !FIELD_OPERATORS.has(op));
if (unsupported.length > 0) {
throw new Error(
`Unsupported Oracle filter operator(s) for field '${metadataKey}': ${unsupported.sort().join(", ")}`,
);
}
const predicates: string[] = [];
const passings: string[] = [];
const additionalClauses: string[] = [];
for (const [operator, operand] of operators) {View on GitHub (pinned to 001c235229)
Solutions
- Omit fields whose operator object is empty before calling search: delete filters.k if Object.keys(v).length === 0.
- Fix the conditional builder so it does not emit the key when no operator applies.
- Validate external filter payloads and strip empty operator objects.
Example fix
// before
const filters = { user_id: {} }; // cond was false
// after
const filters = {};
// or: const filters = cond ? { user_id: { gte: v } } : {}; Defensive patterns
Strategy: validation
Validate before calling
for (const [field, v] of Object.entries(filters)) {
if (v && typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length === 0) {
delete filters[field];
}
} Type guard
const isNonEmptyOpObject = (v: unknown): v is Record<string, any> => typeof v === 'object' && v !== null && !Array.isArray(v) && Object.keys(v).length > 0;
Prevention
- Strip empty operator objects before search
- Avoid spreading conditionally-built operator objects that can be {}
- Validate external filter payloads and drop no-op entries
When it happens
Trigger: Passing filters = { user_id: {} } — e.g. spread of an empty variable or optional operators object where no operator was actually set.
Common situations: Building filters conditionally ({ ...(cond ? { gte: v } : {}) }) where cond is false yields {}; API request bodies with 'filters: {field: {}}'; defaults objects merged until empty.
Related errors
- Oracle filter for field '${metadataKey}' must be a scalar or
- Top-level entity parameters [${invalidKeys.join(", ")}] are
- Invalid ${name}: cannot be empty or whitespace-only. Provide
- Invalid ${name}: cannot contain whitespace. Provide a valid
- AND filter value must be a list of filter dicts, got ${typeo
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/22921a9199495615.
Report an issue: GitHub.