{"record":{"id":"3e88ef51c32ff5d3","repo":"mem0ai/mem0","slug":"filter-value-for-json-stringify-key-must-be-st","errorCode":null,"errorMessage":"Filter value for ${JSON.stringify(key)} must be string, number, or boolean","messagePattern":"Filter value for (.+?) must be string, number, or boolean","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/vector_stores/elasticsearch.ts","lineNumber":40,"sourceCode":"  autoCreateIndex?: boolean;\n  headers?: Record<string, string>;\n}\n\nconst SAFE_FILTER_KEY = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n\n// Mirrors the Python provider's _validate_filter. Filter keys are interpolated\n// into `metadata.${key}` field paths, so reject anything that is not a plain\n// identifier and reject non-scalar values before they reach the query.\nfunction validateFilter(key: string, value: unknown): void {\n  if (typeof key !== \"string\" || !SAFE_FILTER_KEY.test(key)) {\n    throw new Error(`Invalid filter key: ${JSON.stringify(key)}`);\n  }\n  if (\n    typeof value !== \"string\" &&\n    typeof value !== \"number\" &&\n    typeof value !== \"boolean\"\n  ) {\n    throw new Error(\n      `Filter value for ${JSON.stringify(key)} must be string, number, or boolean`,\n    );\n  }\n}\n\nexport class ElasticsearchDB implements VectorStore {\n  private client!: Client;\n  private readonly config: ElasticsearchConfig;\n  private readonly collectionName: string;\n  private readonly dimension: number;\n  private readonly autoCreateIndex: boolean;\n  private _initPromise?: Promise<void>;\n\n  constructor(config: ElasticsearchConfig) {\n    this.config = config;\n    this.collectionName = config.collectionName;\n    this.dimension = config.dimension || config.embeddingModelDims || 1536;\n    this.autoCreateIndex = config.autoCreateIndex !== false;","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/vector_stores/elasticsearch.ts#L22-L58","documentation":"validateFilter() in the Elasticsearch vector store throws when a filter value is not a string, number, or boolean. Non-scalar values (objects, arrays, null, undefined) cannot be mapped onto ES term queries safely, so they are rejected client-side before the query is built.","triggerScenarios":"Calling search/list with a filter value that is an array (e.g. { tags: ['a','b'] }), an object ({ user: { id: 1 } }), null, or undefined.","commonSituations":"Expecting OR-semantics by passing an array of values (not supported here — use $or branches instead); undefined values leaking in from optional fields spread into filters ({...req.query} where a param is absent); null values from JSON configs.","solutions":["Replace array values with an $or branch per value, or store a single scalar field per tag.","Strip undefined/null entries from filter objects before calling search (Object.fromEntries(Object.entries(f).filter(([,v]) => v != null))).","Flatten nested objects into dot-free scalar fields at insert time and filter on those."],"exampleFix":"// before\nawait es.search(query, 5, { tags: ['red', 'blue'], user_id: undefined });\n\n// after\nawait es.search(query, 5, {\n  $or: [{ tags: 'red' }, { tags: 'blue' }],\n});","handlingStrategy":"validation","validationCode":"const isScalar = (v: unknown): v is string | number | boolean =>\n  ['string', 'number', 'boolean'].includes(typeof v);\nconst invalid = Object.entries(filters ?? {}).filter(([, v]) => !isScalar(v));\nif (invalid.length) {\n  throw new Error(`Non-scalar filter values for keys: ${invalid.map(([k]) => k).join(', ')}`);\n}","typeGuard":"type Scalar = string | number | boolean;\nconst isScalarFilterMap = (f: unknown): f is Record<string, Scalar> =>\n  typeof f === 'object' && f !== null &&\n  Object.values(f).every((v) => v === null || ['string', 'number', 'boolean'].includes(typeof v));","tryCatchPattern":null,"preventionTips":["Strip null/undefined entries from filter objects before calling search.","Express multi-value matching with $or branches, not arrays as values.","Flatten structured metadata into scalar fields at insert time."],"tags":["elasticsearch","filters","validation","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}