mem0ai/mem0 · error

messages is required and cannot be undefined or null. Provid

Error message

messages is required and cannot be undefined or null. Provide a string or array of messages.

What it means

The first input validation in Memory.add(): messages must be a string or a Message[] array, and passing undefined or null throws immediately with this message. It exists to fail fast with an actionable message instead of letting a TypeError surface deep in the LLM/embedding pipeline.

Source

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

  }

  async add(
    messages: string | Message[],
    config: AddMemoryOptions,
  ): Promise<SearchResult> {
    if (config?.timestamp !== undefined) {
      await this._getNoticeTelemetryId();
      throw new Error(
        await getTemporalFeatureErrorMessage(this, {
          triggerFunction: "add",
          triggerParameter: "timestamp",
        }),
      );
    }

    // Validate messages input
    if (messages === undefined || messages === null) {
      throw new Error(
        "messages is required and cannot be undefined or null. Provide a string or array of messages.",
      );
    }
    if (Array.isArray(messages)) {
      if (messages.length === 0) {
        throw new Error(
          "messages array cannot be empty. Provide at least one message with non-empty content.",
        );
      }
      const allBlank = messages.every(
        (m) => typeof m.content === "string" && m.content.trim() === "",
      );
      if (allBlank) {
        throw new Error(
          "messages array cannot contain only blank content. Provide at least one message with non-empty content.",
        );
      }
    } else if (messages.trim() === "") {

View on GitHub (pinned to 001c235229)

Solutions

  1. Guard at the call site: if (!messages) throw your own input error before calling add().
  2. Fix the upstream data flow so the variable actually contains the conversation text/array.
  3. Type the parameter as string | Message[] (not optional) so the compiler catches missing args.
  4. Validate request payloads at your API boundary instead of relying on the SDK to catch them.

Example fix

// before
await memory.add(body.messages, { filters: { userId } }); // body.messages undefined -> throws

// after
if (body.messages == null) {
  throw new TypeError('messages is required');
}
await memory.add(body.messages, { filters: { userId } });
Defensive patterns

Strategy: type-guard

Validate before calling

function hasMessages(messages: unknown): boolean {
  return typeof messages === 'string' || Array.isArray(messages);
}

Type guard

function isAddableInput(messages: unknown): messages is string | { role: string; content: string }[] {
  if (typeof messages === 'string') return messages.length > 0;
  return Array.isArray(messages) && messages.length > 0 && messages.every(
    (m) => m && typeof (m as any).content === 'string',
  );
}

Prevention

When it happens

Trigger: Calling memory.add(undefined, ...), memory.add(null, { filters: {...} }), or passing an optional variable that was never assigned — e.g. profile?.bio where bio is missing, or messages dropped between service layers.

Common situations: Optional chaining producing undefined (data?.messages), default parameters omitted, deserialization of a request body whose field is absent, or async race where the payload hasn't loaded when add() is called.

Related errors


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