{"record":{"id":"22921a9199495615","repo":"mem0ai/mem0","slug":"operator-filter-for-field-metadatakey-must-no","errorCode":null,"errorMessage":"Operator filter for field '${metadataKey}' must not be empty","messagePattern":"Operator filter for field '(.+?)' must not be empty","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/vector_stores/oracledb.ts","lineNumber":147,"sourceCode":"  }\n\n  if (isScalar(value)) {\n    if (value === null) {\n      return jsonExists(path, \"@ == null\", []);\n    }\n    const [variable, passing] = bindFilterValue(value, binds);\n    return jsonExists(path, `@ == ${variable}`, [passing]);\n  }\n\n  if (Array.isArray(value)) {\n    throw new Error(\n      `Oracle filter for field '${metadataKey}' must be a scalar or an operator object`,\n    );\n  }\n\n  const operators = Object.entries(value);\n  if (operators.length === 0) {\n    throw new Error(\n      `Operator filter for field '${metadataKey}' must not be empty`,\n    );\n  }\n\n  const unsupported = operators\n    .map(([op]) => op)\n    .filter((op) => !FIELD_OPERATORS.has(op));\n  if (unsupported.length > 0) {\n    throw new Error(\n      `Unsupported Oracle filter operator(s) for field '${metadataKey}': ${unsupported.sort().join(\", \")}`,\n    );\n  }\n\n  const predicates: string[] = [];\n  const passings: string[] = [];\n  const additionalClauses: string[] = [];\n\n  for (const [operator, operand] of operators) {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/vector_stores/oracledb.ts#L129-L165","documentation":"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.","triggerScenarios":"Passing filters = { user_id: {} } — e.g. spread of an empty variable or optional operators object where no operator was actually set.","commonSituations":"Building filters conditionally ({ ...(cond ? { gte: v } : {}) }) where cond is false yields {}; API request bodies with 'filters: {field: {}}'; defaults objects merged until empty.","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."],"exampleFix":"// before\nconst filters = { user_id: {} }; // cond was false\n\n// after\nconst filters = {};\n// or: const filters = cond ? { user_id: { gte: v } } : {};","handlingStrategy":"validation","validationCode":"for (const [field, v] of Object.entries(filters)) {\n  if (v && typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length === 0) {\n    delete filters[field];\n  }\n}","typeGuard":"const isNonEmptyOpObject = (v: unknown): v is Record<string, any> =>\n  typeof v === 'object' && v !== null && !Array.isArray(v) && Object.keys(v).length > 0;","tryCatchPattern":null,"preventionTips":["Strip empty operator objects before search","Avoid spreading conditionally-built operator objects that can be {}","Validate external filter payloads and drop no-op entries"],"tags":["oracledb","filters","validation","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}