mem0ai/mem0 · error · Error

Invalid memory action: ${memoryAction}

Error message

Invalid memory action: ${memoryAction}

What it means

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.

Source

Thrown at mem0-ts/src/oss/src/embeddings/vertexai.ts:161

    return {
      content: text,
      task_type: taskType,
    };
  }

  async embed(
    text: string,
    memoryAction?: "add" | "update" | "search",
  ): Promise<number[]> {
    await this.initClient();
    if (!this.client || !this.helpers) {
      throw new Error("Client not initialized");
    }

    let embeddingType = "SEMANTIC_SIMILARITY";
    if (memoryAction !== undefined) {
      if (!(memoryAction in this.embeddingTypes)) {
        throw new Error(`Invalid memory action: ${memoryAction}`);
      }
      embeddingType = this.embeddingTypes[memoryAction];
    }

    const instance = this.formatInstance(text, embeddingType);
    const parameters = {
      outputDimensionality: this.embeddingDims,
    };

    const [response] = await this.client.predict({
      endpoint: this.endpoint(),
      instances: [this.helpers.toValue(instance) as any],
      parameters: this.helpers.toValue(parameters) as any,
    });

    if (!response.predictions || response.predictions.length === 0) {
      throw new Error("No predictions returned from Vertex AI");
    }

View on GitHub (pinned to 001c235229)

Solutions

  1. Pass only 'add', 'update', or 'search', or omit the argument to use the default SEMANTIC_SIMILARITY task
  2. Validate/normalize the action string before calling embed() (lowercase it, map synonyms like 'query' -> 'search')
  3. Keep the call site in TypeScript so the literal-union type rejects bad values at compile time

Example fix

// before
await embedder.embed(text, action as any); // action from user input

// after
const action = ["add", "update", "search"].includes(raw) ? raw : undefined;
await embedder.embed(text, action);
Defensive patterns

Strategy: validation

Validate before calling

const MEMORY_ACTIONS = new Set(["add", "update", "search"]);
const action = MEMORY_ACTIONS.has(rawAction) ? (rawAction as "add" | "update" | "search") : undefined;
await embedder.embed(text, action);

Type guard

function isMemoryAction(v: unknown): v is "add" | "update" | "search" {
  return v === "add" || v === "update" || v === "search";
}
function isInvalidMemoryActionError(err: unknown): boolean {
  return err instanceof Error && err.message.startsWith("Invalid memory action:");
}

Try / catch

try { await embedder.embed(text, action); }
catch (err) {
  if (err instanceof Error && err.message.startsWith("Invalid memory action:")) {
    return embedder.embed(text); // retry with default task type
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: Calling the lower-level embed() API directly with an action vocabulary that does not match add/update/search; case mismatches; forwarding unvalidated external strings.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/c521e307a7ad41f3. Report an issue: GitHub.