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

  1. 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
  2. If wrapping generate/stream, forward the original user input into the title-generation options instead of dropping it
  3. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/cae11ed228ea9eca. Report an issue: GitHub.