mastra-ai/mastra · error

@mastra/livekit: MastraVoiceAgent requires `agent` or `gener

Error message

@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`.

What it means

The MastraVoiceAgent constructor requires exactly one reply source: a Mastra `agent` instance or a `generate` function. When neither is provided, the constructor's else branch throws this error, because without a reply source the agent's llmNode would have nothing to produce voice replies with.

Source

Thrown at integrations/livekit/src/bridge.ts:474

      this.reminder = new DisclosureReminder(
        options.greetingReminder.everyMs,
        options.greetingReminder.text?.trim() || DEFAULT_DISCLOSURE_REMINDER,
      );
    }

    if (options.generate) {
      this.replyGenerator = options.generate;
    } else if (options.agent) {
      this.mastraAgent = options.agent;
      this.replyGenerator = createAgentReplyGenerator({
        agent: options.agent,
        streamOptions: options.streamOptions,
        toolFeedback: options.toolFeedback,
        onToolCall: options.onToolCall,
        onTurnComplete: options.onTurnComplete,
      });
    } else {
      throw new Error('@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`.');
    }
  }

  override async llmNode(
    chatCtx: llm.ChatContext,
    _toolCtx: llm.ToolContext,
    _modelSettings: voice.ModelSettings,
  ): Promise<ReadableStream<llm.ChatChunk | string> | null> {
    const messages: VoiceTurnMessage[] =
      this.memory === false ? chatContextToMessages(chatCtx) : extractNewTurnMessages(chatCtx);
    if (messages.length === 0) return null;

    const reply = await this.replyGenerator({
      messages,
      chatCtx,
      memory: this.memory,
      requestContext: this.requestContext,
      tracingContext: this.streamOptions?.tracingContext,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass a Mastra agent instance: new MastraVoiceAgent({ agent: myAgent }).
  2. Or pass a custom reply function: new MastraVoiceAgent({ generate: async (ctx) => '...' }).
  3. Check options-building code so at least one of agent/generate is always assigned; validate before constructing.

Example fix

// before
new MastraVoiceAgent({ id: 'va', instructions: 'You are helpful' })
// after
new MastraVoiceAgent({ id: 'va', instructions: 'You are helpful', agent: new Agent({ name: 'assistant', instructions: '...', model }) })
Defensive patterns

Strategy: validation

Validate before calling

function assertHasReplySource(o: MastraVoiceAgentOptions): void {
  if (!o.agent && !o.generate) {
    throw new Error('MastraVoiceAgent requires `agent` or `generate`');
  }
}

Type guard

function hasReplySource(o: MastraVoiceAgentOptions): o is MastraVoiceAgentOptions & ({ agent: NonNullable<MastraVoiceAgentOptions['agent']> } | { generate: NonNullable<MastraVoiceAgentOptions['generate']> }) {
  return Boolean(o.agent || o.generate);
}

Prevention

When it happens

Trigger: new MastraVoiceAgent({ id, instructions, ... }) with neither `agent` nor `generate` in options — e.g. building options dynamically and both branches that set them failing to run, or calling with only metadata options.

Common situations: Conditional code like `if (useAgent) opts.agent = a; if (useGenerate) opts.generate = g;` where neither condition matched; deserialized/parsed config that dropped function-valued `generate`; forgetting to import/instantiate the Mastra agent and passing undefined.

Related errors


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