mastra-ai/mastra · error · Error
Either message or messages must be provided
Error message
Either message or messages must be provided
What it means
Thrown during agent title generation when neither a single `message` nor a `messages` array was supplied to the title-generation path. The library needs at least one user message to derive a conversation title from, so it fails fast instead of returning a meaningless or empty title.
Source
Thrown at packages/core/src/agent/agent.ts:3662
// for storage/observability. Idempotent.
if (this.#mastra) {
llm.__registerMastra(this.#mastra);
}
let userContent: string;
if (messages && messages.length > 0) {
// Multi-message path: format all messages with roles
userContent = this.formatMessagesForTitle(messages);
} else if (message) {
// Single message path (backward compat): normalize and format
const normMessage = new MessageList().add(message, 'user').get.all.aiV5.ui().at(-1);
if (!normMessage) {
throw new Error(`Could not generate title from input ${JSON.stringify(message)}`);
}
userContent = this.formatMessagesForTitle([normMessage]);
} else {
throw new Error('Either message or messages must be provided');
}
if (!userContent) {
return undefined;
}
// Resolve instructions using the dedicated method
const systemInstructions = await this.resolveTitleInstructions(requestContext, instructions);
let text = '';
if (isSupportedLanguageModel(llm.getModel())) {
const messageList = new MessageList()
.add(
[
{
role: 'system',
content: systemInstructions,View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure you pass either `message` (a single message object/string) or a non-empty `messages` array when invoking generation on an agent with title generation enabled
- If wrapping generate/stream, forward the original user input into the title-generation options instead of dropping it
- Check that the memory/thread integration isn't calling title generation with an empty payload; skip title generation when input is empty
Example fix
// before
await agent.generate('', { memory: { thread: threadId } });
// after
await agent.generate('Plan my trip to Kyoto', { memory: { thread: threadId } }); Defensive patterns
Strategy: validation
Validate before calling
function canGenerateTitle(input) {
const hasMessage = input?.message != null;
const hasMessages = Array.isArray(input?.messages) && input.messages.length > 0;
return hasMessage || hasMessages;
} Type guard
function hasTitleInput(opts) {
return (
opts != null &&
(('message' in opts && opts.message != null) ||
(Array.isArray(opts.messages) && opts.messages.length > 0))
);
} Try / catch
try {
await agent.generate(prompt, opts);
} catch (e) {
if (e?.message === 'Either message or messages must be provided') {
logger.warn('skipping title generation: no input messages');
return;
}
throw e;
} Prevention
- Never call generation with empty/undefined input when thread title generation is enabled
- Forward the original user input through any wrappers/middleware
- Skip title generation for empty conversations instead of invoking the agent
When it happens
Trigger: Calling the internal/indirect title generation flow (e.g. via agent configuration that auto-generates titles for threads) with both `message` and `messages` undefined or null; passing an explicit `messages: []` empty array can also route here with no usable input.
Common situations: Custom wrappers or middleware around `agent.generate()` that strip or forget to forward the input messages when title generation is enabled; programmatic thread creation with no initial user content; storage/memory integrations that invoke title generation with sanitized/emptied payloads.
Related errors
- AGENT_REQUEST_CONTEXT_VALIDATION_FAILED
- Could not generate title from input ${JSON.stringify(message
- AGENT_LIST_SUSPENDED_RUNS_INVALID_PER_PAGE
- AGENT_LIST_SUSPENDED_RUNS_INVALID_PAGE
- AGENT_SEND_STREAM_RESUME_MISSING_TARGET
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/cae11ed228ea9eca.
Report an issue: GitHub.