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
- Guard at the call site: if (!messages) throw your own input error before calling add().
- Fix the upstream data flow so the variable actually contains the conversation text/array.
- Type the parameter as string | Message[] (not optional) so the compiler catches missing args.
- 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
- Type the argument as string | Message[] (non-optional) at your own function boundaries.
- Validate request payloads before they reach Memory instead of relying on SDK checks.
- Beware optional chaining: data?.messages is undefined when the field is absent.
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
- messages array cannot be empty. Provide at least one message
- Either memoryId or --all is required
- At least one entity ID is required for deleteEntities.
- Unknown LLM provider: ${providerId}
- Unknown embedder provider: ${providerId}
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/faf99a2713e845d8.
Report an issue: GitHub.