{"record":{"id":"7a5b7a365ff38a33","repo":"mastra-ai/mastra","slug":"validation-messages-join","errorCode":null,"errorMessage":"validation.messages.join(', ')","messagePattern":"validation\\.messages\\.join\\(', '\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/vector/filter/base.ts","lineNumber":293,"sourceCode":"    NOT_REQUIRES_OBJECT: `$not operator requires an object`,\n    NOT_CANNOT_BE_EMPTY: `$not operator cannot be empty`,\n    INVALID_LOGICAL_OPERATOR_CONTENT: (path: string) =>\n      `Logical operators must contain field conditions, not direct operators: ${path}`,\n    INVALID_TOP_LEVEL_OPERATOR: (op: string) => `Invalid top-level operator: ${op}`,\n    ELEM_MATCH_REQUIRES_OBJECT: `$elemMatch requires an object with conditions`,\n  } as const;\n\n  /**\n   * Helper to handle array value normalization consistently\n   */\n  protected normalizeArrayValues(values: any[]): any[] {\n    return values.map(value => this.normalizeComparisonValue(value));\n  }\n\n  protected validateFilter(filter: Filter): void {\n    const validation = this.validateFilterSupport(filter);\n    if (!validation.supported) {\n      throw new Error(validation.messages.join(', '));\n    }\n  }\n\n  /**\n   * Validates if a filter structure is supported by the specific vector DB\n   * and returns detailed validation information.\n   */\n  private validateFilterSupport(\n    node: Filter,\n    path: string = '',\n  ): {\n    supported: boolean;\n    messages: string[];\n  } {\n    const messages: string[] = [];\n\n    // Handle primitives and empty values\n    if (this.isPrimitive(node) || this.isEmpty(node)) {","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/vector/filter/base.ts#L275-L311","documentation":"`validateFilter` runs the vector-store adapter's `validateFilterSupport` check before translating a filter; when the adapter reports `supported: false`, it throws an error whose message is all unsupported-feature messages joined with ', '. This surfaces, per vector DB, which filter operators/structures (e.g. `$regex`, nested logical groups, `$elemMatch`) the backend does not implement.","triggerScenarios":"Calling `vector.query(...)`/`translate(filter)` (or storage-backed memory queries) with a filter using operators the chosen adapter doesn't support — e.g. `$not` or `$elemMatch` on a backend lacking them, or mixing top-level operators unsupported by pgvector/MongoDB/other adapters.","commonSituations":"Porting code between vector stores (Mongo -> pgvector) and reusing filter shapes; LLM-generated filters including fancy operators; docs examples copied across adapters.","solutions":["Read the joined messages — they enumerate exactly which operators/structures are unsupported; remove or rewrite those filter parts.","Simplify the filter to the adapter's supported subset (e.g. replace `$not` with explicit complement conditions).","Do client-side filtering: fetch with supported filter conditions, then apply the unsupported predicate in JS after results return.","Switch to a vector store adapter that supports the filter features you need, or check the adapter docs for its filter capability matrix."],"exampleFix":"// before\nawait store.query({ filter: { $not: { status: 'draft' } } }); // unsupported\n// after\nawait store.query({ filter: { status: { $ne: 'draft' } } }); // or filter results in JS","handlingStrategy":"fallback","validationCode":"const UNSUPPORTED = [/\\$not/, /\\$elemMatch/, /\\$regex/]; // adjust per adapter\nfunction assertFilterSupported(filter: Record<string, unknown>) {\n  for (const key of Object.keys(filter)) {\n    if (UNSUPPORTED.some(re => re.test(key))) throw new Error(`Operator ${key} unsupported by this vector store`);\n  }\n}","typeGuard":"function usesOnlySupportedOps(filter: Record<string, unknown>, allowed: string[]): boolean {\n  return Object.keys(filter).every(k => allowed.includes(k) || k === 'id');\n}","tryCatchPattern":"try {\n  results = await store.query({ index, filter });\n} catch (e) {\n  if (e instanceof Error && /not supported|unsupported/i.test(e.message)) {\n    results = (await store.query({ index })).filter(postFilterInJs);\n  } else throw e;\n}","preventionTips":["Check the adapter's filter-capability docs before using logical/nested operators ($not, $elemMatch, $regex).","Keep a per-store filter allowlist and validate filters before querying when the store is configurable.","Prefer simple equality/in-range filters for portable code across vector stores; post-filter unsupported predicates in application code."],"tags":["vector","filter","validation","compatibility"],"backgroundTag":"unsupported-filter-operator","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}