mastra-ai/mastra · error
BUG: add handling for message role ${message.role} in messag
Error message
BUG: add handling for message role ${message.role} in message ${JSON.stringify(message, null, 2)} What it means
TypeDetector.getRole maps input message roles to the internal MastraDBMessage role ('user' | 'assistant' | 'system'); roles outside 'assistant' | 'tool' | 'user' | 'system' hit this 'BUG:' assertion. It is an internal invariant guard flagging an unsupported role that upstream code failed to filter.
Source
Thrown at packages/core/src/agent/message-list/detection/TypeDetector.ts:278
if (part.type === 'reasoning' && 'signature' in part) return false;
if (part.type === 'redacted-reasoning') return false;
}
// If no distinguishing features are found, the message shape is still
// compatible with the v5 model format.
return true;
}
/**
* Get the normalized role for a message
* Maps `tool` to `assistant` because tool messages are displayed as part of
* the assistant conversation.
*/
static getRole(message: MessageInput): MastraDBMessage['role'] {
if (message.role === 'assistant' || message.role === 'tool') return 'assistant';
if (message.role === 'user') return 'user';
if (message.role === 'system') return 'system';
throw new Error(
`BUG: add handling for message role ${message.role} in message ${JSON.stringify(message, null, 2)}`,
);
}
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Filter or remap unsupported roles ('function' -> merge into assistant tool-call history) before adding messages
- Migrate stored messages to the supported role set
- Validate message shape at your ingestion boundary
- Report the triggering input as a bug if it comes from a supported AI SDK version
Example fix
// before
add({ role: 'function', name: 'x', content: '...' })
// after
add({ role: 'tool', content: [{ type: 'tool-result', toolName: 'x', ... }] }) Defensive patterns
Strategy: type-guard
Validate before calling
const ACCEPTED = ['user','assistant','tool','system'];
if (!ACCEPTED.includes(msg.role)) throw new Error(`Role ${msg.role} not supported by MessageList`); Type guard
function isSupportedRole(r: string): r is 'user'|'assistant'|'tool'|'system' { return ['user','assistant','tool','system'].includes(r); } Try / catch
try { memory.addMessages([msg]); } catch (e) { if (e instanceof Error && e.message.startsWith('BUG: add handling for message role')) { console.error('Unsupported message role in input:', msg.role); } throw e; } Prevention
- Migrate legacy 'function'-role messages before ingestion
- Validate message roles when reading from custom storage
- Test custom adapters against MessageList with all role shapes
When it happens
Trigger: fromUIMessage or fromCoreMessage receiving a message whose role is anything other than user/assistant/tool/system — e.g. role 'function' from a legacy CoreMessage or a custom role string.
Common situations: Feeding AI SDK v3/v4 'function'-role messages into modern Memory; custom storage adapters returning stale message shapes; corrupt or hand-edited persistence records.
Related errors
- countCoreSystemMessageTokens can only be used with system me
- Expected role "system" but saw ${coreMessage.role} for messa
- INVALID_MESSAGE_CONTENT
- INVALID_SYSTEM_MESSAGE_FORMAT
- Missing message source for message ${message}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/26d66354927aea52.
Report an issue: GitHub.