{"record":{"id":"0e92a96717f95102","repo":"mastra-ai/mastra","slug":"expected-role-system-but-saw-coremessage-role","errorCode":null,"errorMessage":"Expected role \"system\" but saw ${coreMessage.role} for message ${JSON.stringify(coreMessage, null, 2)}","messagePattern":"Expected role \"system\" but saw (.+?) for message (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/message-list/message-list.ts","lineNumber":1578,"sourceCode":"      | string[]\n      | null,\n    tag?: string,\n  ) {\n    if (!messages) return this;\n    for (const message of Array.isArray(messages) ? messages : [messages]) {\n      this.addOneSystem(message, tag);\n    }\n    return this;\n  }\n\n  private addOneSystem(\n    message: CoreMessageV4 | AIV6Type.ModelMessage | AIV5Type.ModelMessage | MastraDBMessage | string,\n    tag?: string,\n  ) {\n    const coreMessage = systemMessageToAIV4Core(message);\n\n    if (coreMessage.role !== `system`) {\n      throw new Error(\n        `Expected role \"system\" but saw ${coreMessage.role} for message ${JSON.stringify(coreMessage, null, 2)}`,\n      );\n    }\n\n    if (tag && !this.isDuplicateSystem(coreMessage, tag)) {\n      this.taggedSystemMessages[tag] ||= [];\n      this.taggedSystemMessages[tag].push(coreMessage);\n      if (this.isRecording) {\n        this.recordedEvents.push({\n          type: 'addSystem',\n          tag,\n          message: coreMessage,\n        });\n      }\n    } else if (!tag && !this.isDuplicateSystem(coreMessage)) {\n      this.systemMessages.push(coreMessage);\n      if (this.isRecording) {\n        this.recordedEvents.push({","sourceCodeStart":1560,"sourceCodeEnd":1596,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/message-list/message-list.ts#L1560-L1596","documentation":"MessageList.addSystem asserts that everything passed to it is a system message. systemMessageToAIV4Core normalized the input, and if the resulting coreMessage.role is not 'system', the call site passed a non-system message (or an unconvertible shape) to addSystem, so it throws.","triggerScenarios":"Calling messageList.addSystem() with a user/assistant message, a plain object missing a role, or a string-producing conversion that yields a non-system role; also passing MastraDBMessages whose role was mutated.","commonSituations":"Using addSystem as a generic add() by mistake; dynamic system-prompt injection passing a variable that is not always a system message; typed-erased inputs from JS callers.","solutions":["Only pass messages with role 'system' (or plain strings) to addSystem","Route non-system messages to messageList.add() instead","Log/inspect the JSON in the error to identify the wrongly-typed input","Add a compile-time constraint (SystemMessage type) in your calling code"],"exampleFix":"// before\nmessageList.addSystem({ role: 'user', content: 'instructions' })\n// after\nmessageList.addSystem({ role: 'system', content: 'instructions' })","handlingStrategy":"validation","validationCode":"if (typeof msg !== 'string' && msg.role !== 'system') throw new Error('addSystem requires a system message');","typeGuard":"function isSystemMessage(m: any): m is { role: 'system'; content: string | any[] } { return typeof m === 'string' || m?.role === 'system'; }","tryCatchPattern":"try { messageList.addSystem(msg); } catch (e) { if (e instanceof Error && e.message.includes('Expected role \"system\"')) { messageList.add(msg); } else throw e; }","preventionTips":["Only call addSystem for system-prompt content","Type inputs as SystemMessage in calling code","Avoid passing dynamic variables of uncertain role into addSystem"],"tags":["message-list","system-message","invalid-role"],"backgroundTag":"invalid-message-role","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}