{"record":{"id":"9afb29794f049876","repo":"mem0ai/mem0","slug":"oracle-filter-operator-operator-does-not-supp","errorCode":null,"errorMessage":"Oracle filter operator '${operator}' does not support null","messagePattern":"Oracle filter operator '(.+?)' does not support null","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/vector_stores/oracledb.ts","lineNumber":174,"sourceCode":"    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) {\n    if (operator in COMPARISON_OPERATORS) {\n      if (!isScalar(operand)) {\n        throw new Error(\n          `Oracle filter operator '${operator}' requires a scalar value`,\n        );\n      }\n      if (operand === null) {\n        if (operator !== \"eq\" && operator !== \"ne\") {\n          throw new Error(\n            `Oracle filter operator '${operator}' does not support null`,\n          );\n        }\n        predicates.push(`@ ${COMPARISON_OPERATORS[operator]} null`);\n        continue;\n      }\n      const [variable, passing] = bindFilterValue(operand, binds);\n      predicates.push(`@ ${COMPARISON_OPERATORS[operator]} ${variable}`);\n      passings.push(passing);\n      continue;\n    }\n\n    if (operator === \"in\" || operator === \"nin\") {\n      if (!Array.isArray(operand) || operand.length === 0) {\n        throw new Error(\n          `Oracle filter operator '${operator}' requires a non-empty array`,\n        );\n      }","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/vector_stores/oracledb.ts#L156-L192","documentation":"Comparison operators gt, gte, lt, lte cannot compare against SQL/JSON NULL, so the adapter only permits null as the operand of eq and ne. Any other comparison operator with a null operand is rejected before SQL generation because Oracle JSON_EXISTS would not produce meaningful results.","triggerScenarios":"Filters such as { score: { gt: null } }, { updated_at: { lte: null } }, or dynamically built filters where a variable evaluated to null/undefined-coerced-to-null for a range operator.","commonSituations":"Optional filter parameters defaulting to null and inserted into range operators unconditionally; API code passing through client-supplied nulls; attempting an 'exists/is not null' check by comparing against null (use the '*' presence value or ne: null instead).","solutions":["Use { field: { ne: null } } for 'is not null' and { field: { eq: null } } for 'is null'.","Use the field-presence form { field: '*' } to test that the key exists in the JSON payload.","Strip null operands from range operators in your filter-building code before calling search().","Make optional range bounds conditional: only add { field: { gte: x } } when x is not null."],"exampleFix":"// before\nfilters = { score: { gt: null } }; // meaningless\n\n// after\nfilters = { score: { ne: null } }; // field exists and is not null","handlingStrategy":"validation","validationCode":"function stripNullRangeBounds(filters: any): any {\n  if (Array.isArray(filters)) return filters.map(stripNullRangeBounds);\n  if (!filters || typeof filters !== 'object') return filters;\n  const out: Record<string, any> = {};\n  for (const [k, v] of Object.entries(filters)) {\n    if (v && typeof v === 'object' && !Array.isArray(v)) {\n      const ops = Object.fromEntries(Object.entries(v).filter(([op, val]) => !(val === null && !['eq','ne'].includes(op))));\n      if (Object.keys(ops).length) out[k] = ops;\n    } else out[k] = v;\n  }\n  return out;\n}","typeGuard":null,"tryCatchPattern":"try { await memory.search('q', { filters }); } catch (e) { if (e instanceof Error && e.message.includes('does not support null')) { /* change the operator to ne/eq or remove the null bound */ } else throw e; }","preventionTips":["Express null checks only as { eq: null } or { ne: null }.","Use { field: '*' } for existence checks.","Make optional range bounds conditional instead of null-filled."],"tags":["oracle","filters","null-handling","validation"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}