{"record":{"id":"d1844bbd7e68a174","repo":"mem0ai/mem0","slug":"invalid-filter-key-json-stringify-key","errorCode":null,"errorMessage":"Invalid filter key: ${JSON.stringify(key)}","messagePattern":"Invalid filter key: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/vector_stores/elasticsearch.ts","lineNumber":33,"sourceCode":"  password?: string;\n  collectionName: string;\n  embeddingModelDims: number;\n  dimension?: number;\n  useSsl?: boolean;\n  caCerts?: string;\n  verifyCerts?: boolean;\n  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;","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/vector_stores/elasticsearch.ts#L15-L51","documentation":"validateFilter() in the Elasticsearch vector store throws when a filter key is not a plain identifier matching ^[a-zA-Z_][a-zA-Z0-9_]*$. Filter keys are interpolated directly into metadata.${key} field paths in ES queries, so keys with dots, brackets, spaces, or special characters could alter query semantics (or enable query injection), and are rejected before reaching Elasticsearch.","triggerScenarios":"Calling search/list/delete with filters whose keys contain dots (e.g. 'user.id'), hyphens ('agent-id'), spaces, leading digits ('2fa'), or when the key is not a string at all. Nested object filter shapes like { metadata: { user_id: 'x' } } also produce invalid keys.","commonSituations":"Using metadata keys with dots or hyphens that Elasticsearch would otherwise interpret as nested field paths; passing a nested/wrapped filter object instead of a flat one; dynamic filter keys sourced from user input containing arbitrary characters.","solutions":["Use flat keys that are plain identifiers: { user_id: 'u1' } — no dots, hyphens, or spaces.","Rename metadata fields at write time (insert payload keys must also be identifiers) so lookups stay valid.","If filter keys come from user input, sanitize/whitelist them before calling search.","Avoid wrapping filters in an extra object level; pass the key/value map directly."],"exampleFix":"// before\nawait es.search(query, 5, { 'user.id': 'u1', 'agent-id': 'a1' });\n\n// after\nawait es.search(query, 5, { user_id: 'u1', agent_id: 'a1' });","handlingStrategy":"validation","validationCode":"const SAFE_KEY = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\nconst badKeys = Object.keys(filters ?? {}).filter((k) => !SAFE_KEY.test(k));\nif (badKeys.length) throw new Error(`Invalid filter keys: ${badKeys.join(', ')}`);","typeGuard":"const SAFE_KEY = /^[a-zA-Z_][a-zA-Z0-9_]*$/;\nconst hasSafeFilterKeys = (f: unknown): f is Record<string, string | number | boolean> =>\n  typeof f === 'object' && f !== null &&\n  Object.keys(f).every((k) => SAFE_KEY.test(k));","tryCatchPattern":null,"preventionTips":["Restrict metadata field names to plain identifiers (letters, digits, underscore, no leading digit) at insert time.","Never build filter keys from raw user input without whitelisting.","Keep filters flat — no nested objects or dotted paths."],"tags":["elasticsearch","filters","injection-guard","validation","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}