{"record":{"id":"b8a7ffe060c213bd","repo":"mastra-ai/mastra","slug":"invalid-message-content","errorCode":"INVALID_MESSAGE_CONTENT","errorMessage":"Message with role \"${message.role}\" must have either a 'content' property (string or array) or a 'parts' property (array) that is not empty, null, or undefined. Received message: ${JSON.stringify(message, null, 2)}","messagePattern":"Message with role \"(.+?)\" must have either a 'content' property \\(string or array\\) or a 'parts' property \\(array\\) that is not empty, null, or undefined\\. Received message: (.+?)","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/message-list/message-list.ts","lineNumber":1649,"sourceCode":"    const existingMessage = this.getMessageById(message.id);\n    if (!existingMessage) return { exists: false };\n\n    return {\n      exists: true,\n      shouldReplace: !messagesAreEqual(existingMessage, message),\n      id: existingMessage.id,\n    };\n  }\n\n  private addOne(message: MessageInput, messageSource: MessageSource, options: MessageListAddOptions = {}) {\n    if (\n      (!(`content` in message) ||\n        (!message.content &&\n          // allow empty strings\n          typeof message.content !== 'string')) &&\n      (!(`parts` in message) || !message.parts)\n    ) {\n      throw new MastraError({\n        id: 'INVALID_MESSAGE_CONTENT',\n        domain: ErrorDomain.AGENT,\n        category: ErrorCategory.USER,\n        text: `Message with role \"${message.role}\" must have either a 'content' property (string or array) or a 'parts' property (array) that is not empty, null, or undefined. Received message: ${JSON.stringify(message, null, 2)}`,\n        details: {\n          role: message.role as string,\n          messageSource,\n          hasContent: 'content' in message,\n          hasParts: 'parts' in message,\n        },\n      });\n    }\n\n    if (message.role === `system`) {\n      // In the past system messages were accidentally stored in the db. these should be ignored because memory is not supposed to store system messages.\n      if (messageSource === `memory`) return null;\n\n      // Check if the message is in a supported format for system messages","sourceCodeStart":1631,"sourceCodeEnd":1667,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/message-list/message-list.ts#L1631-L1667","documentation":"MessageList.add validates that every incoming message has usable content: either a 'content' string/array or a 'parts' array. A MastraError with id INVALID_MESSAGE_CONTENT (AGENT domain, USER category) is thrown when both are missing, null, or undefined, because an empty message cannot be stored or converted to a prompt.","triggerScenarios":"Adding messages like { role: 'user' } with no content, content: null, content: undefined, or an object with parts: null — via messageList.add(), Memory remember/add flows, or client-supplied message payloads.","commonSituations":"API clients posting empty messages; failed LLM responses persisted with undefined content; JS callers (no type checking) omitting content; mapping code that drops content during transformation.","solutions":["Ensure every message has non-null 'content' (string '' allowed) or a non-empty 'parts' array before calling add()","Validate/sanitize client-supplied messages at your API boundary","Fix transformation code that strips the content field","Catch MastraError with id INVALID_MESSAGE_CONTENT and reject the input upstream with a clearer message"],"exampleFix":"// before\nadd({ role: 'user', content: undefined })\n// after\nadd({ role: 'user', content: '' }) // or omit the message entirely if empty","handlingStrategy":"validation","validationCode":"function hasContent(m: any): boolean { return Boolean(m && m.role && ((('content' in m) && (typeof m.content === 'string' || Array.isArray(m.content))) || Array.isArray(m.parts))); }","typeGuard":"function isAddableMessage(m: any): m is { role: 'user'|'assistant'|'system'|'tool'; content: string | any[] } { return !!m && ['user','assistant','system','tool'].includes(m.role) && (typeof m.content === 'string' || Array.isArray(m.content) || Array.isArray(m.parts)); }","tryCatchPattern":"try { messageList.add(msg); } catch (e) { if (e instanceof MastraError && e.id === 'INVALID_MESSAGE_CONTENT') { console.warn('Skipping empty message', msg); return; } throw e; }","preventionTips":["Validate client-supplied message payloads before persistence","Guard against null/undefined content in transformation pipelines","Allow empty strings but reject null/undefined content","Reject or drop empty messages at the API boundary"],"tags":["message-list","validation","empty-content"],"backgroundTag":"invalid-message-content-part","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}