{"record":{"id":"c521e307a7ad41f3","repo":"mem0ai/mem0","slug":"invalid-memory-action-memoryaction","errorCode":null,"errorMessage":"Invalid memory action: ${memoryAction}","messagePattern":"Invalid memory action: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/embeddings/vertexai.ts","lineNumber":161,"sourceCode":"    return {\n      content: text,\n      task_type: taskType,\n    };\n  }\n\n  async embed(\n    text: string,\n    memoryAction?: \"add\" | \"update\" | \"search\",\n  ): Promise<number[]> {\n    await this.initClient();\n    if (!this.client || !this.helpers) {\n      throw new Error(\"Client not initialized\");\n    }\n\n    let embeddingType = \"SEMANTIC_SIMILARITY\";\n    if (memoryAction !== undefined) {\n      if (!(memoryAction in this.embeddingTypes)) {\n        throw new Error(`Invalid memory action: ${memoryAction}`);\n      }\n      embeddingType = this.embeddingTypes[memoryAction];\n    }\n\n    const instance = this.formatInstance(text, embeddingType);\n    const parameters = {\n      outputDimensionality: this.embeddingDims,\n    };\n\n    const [response] = await this.client.predict({\n      endpoint: this.endpoint(),\n      instances: [this.helpers.toValue(instance) as any],\n      parameters: this.helpers.toValue(parameters) as any,\n    });\n\n    if (!response.predictions || response.predictions.length === 0) {\n      throw new Error(\"No predictions returned from Vertex AI\");\n    }","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/embeddings/vertexai.ts#L143-L179","documentation":"VertexAIEmbedder.embed() maps an optional memoryAction ('add' | 'update' | 'search') to a Vertex task type via a lookup table. If memoryAction is defined but not a key of embeddingTypes (i.e. anything other than add/update/search), it throws before making any API call. At the type level this is already narrowed, so runtime hits come from untyped callers.","triggerScenarios":"JavaScript callers (or 'as any' casts) passing values like 'delete', 'ADD', 'query', or '' as the second argument to embed(); memory pipelines forwarding an arbitrary action string from user input or LLM output into the embedder.","commonSituations":"Calling the lower-level embed() API directly with an action vocabulary that does not match add/update/search; case mismatches; forwarding unvalidated external strings.","solutions":["Pass only 'add', 'update', or 'search', or omit the argument to use the default SEMANTIC_SIMILARITY task","Validate/normalize the action string before calling embed() (lowercase it, map synonyms like 'query' -> 'search')","Keep the call site in TypeScript so the literal-union type rejects bad values at compile time"],"exampleFix":"// before\nawait embedder.embed(text, action as any); // action from user input\n\n// after\nconst action = [\"add\", \"update\", \"search\"].includes(raw) ? raw : undefined;\nawait embedder.embed(text, action);","handlingStrategy":"validation","validationCode":"const MEMORY_ACTIONS = new Set([\"add\", \"update\", \"search\"]);\nconst action = MEMORY_ACTIONS.has(rawAction) ? (rawAction as \"add\" | \"update\" | \"search\") : undefined;\nawait embedder.embed(text, action);","typeGuard":"function isMemoryAction(v: unknown): v is \"add\" | \"update\" | \"search\" {\n  return v === \"add\" || v === \"update\" || v === \"search\";\n}\nfunction isInvalidMemoryActionError(err: unknown): boolean {\n  return err instanceof Error && err.message.startsWith(\"Invalid memory action:\");\n}","tryCatchPattern":"try { await embedder.embed(text, action); }\ncatch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Invalid memory action:\")) {\n    return embedder.embed(text); // retry with default task type\n  }\n  throw err;\n}","preventionTips":["Whitelist memoryAction values at the boundary where external strings enter","Use the literal-union type instead of string/as any","Omit the argument when the task type does not matter"],"tags":["vertexai","validation","embeddings","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}