mem0ai/mem0 · error

At least one of text, metadata, or expirationDate must be pr

Error message

At least one of text, metadata, or expirationDate must be provided.

What it means

Thrown by Memory.update() when none of text, metadata, or expirationDate is supplied. update() supports text-only, metadata-only, and expiration-only updates (a metadata-only update re-indexes the stored text), so it needs to know at least what to change. The deprecated data option is treated as text if text is absent, so passing only data does NOT trigger this.

Source

Thrown at mem0-ts/src/oss/src/memory/index.ts:1675

    const options: UpdateMemoryOptions =
      typeof config === "string" ? { text: config } : config;

    const { data, metadata, expirationDate } = options;
    let text = options.text;

    if (data != null) {
      logger.warn(
        "The `data` option of update() is deprecated and will be removed in " +
          "the next major release. Use `text` instead.",
      );
      if (text == null) {
        text = data;
      }
    }

    if (text == null && metadata == null && expirationDate === undefined) {
      throw new Error(
        "At least one of text, metadata, or expirationDate must be provided.",
      );
    }

    const updateMetadata: Record<string, any> = { ...metadata };
    if (expirationDate !== undefined) {
      updateMetadata.expiration_date =
        expirationDate === null
          ? null
          : normalizeExpirationDate(expirationDate);
    }

    const existingEmbeddings: Record<string, number[]> = {};
    if (text != null) {
      existingEmbeddings[text] = await this.embedder.embed(text, "update");
    }

    await this.updateMemory(memoryId, text, existingEmbeddings, updateMetadata);

View on GitHub (pinned to 001c235229)

Solutions

  1. Pass at least one field: memory.update(id, { text: 'new value' }) or { metadata: {...} } or { expirationDate: '2026-12-31' }
  2. Filter undefined keys out of the payload before calling: Object.fromEntries(Object.entries(opts).filter(([, v]) => v !== undefined))
  3. If you only want to change expiry, pass expirationDate (null clears it) — text and metadata can stay omitted

Example fix

// before
await memory.update(memoryId, updatePayload); // all fields undefined

// after
const payload = Object.fromEntries(
  Object.entries(updatePayload).filter(([, v]) => v !== undefined),
);
if (Object.keys(payload).length) {
  await memory.update(memoryId, payload);
}
Defensive patterns

Strategy: validation

Validate before calling

const patch = Object.fromEntries(
  Object.entries(opts).filter(([, v]) => v !== undefined),
);
if (!('text' in patch) && !('metadata' in patch) && !('expirationDate' in patch)) {
  throw new Error('update() needs text, metadata, or expirationDate');
}
await memory.update(id, patch);

Type guard

const isUpdatePayload = (p: unknown): p is { text?: string; metadata?: Record<string, unknown>; expirationDate?: string | null } =>
  typeof p === 'object' && p !== null &&
  ('text' in p || 'metadata' in p || 'expirationDate' in p);

Prevention

When it happens

Trigger: Calling memory.update(memoryId, {}) — no text, metadata null, expirationDate undefined. Also update(memoryId, { metadata: undefined }) since undefined fails the null/undefined checks.

Common situations: Building the update payload dynamically and all fields end up undefined; calling update just to 'touch' a memory (not supported); migrating from an older API shape where an empty body was a no-op.

Related errors


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