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
- Pass a Mastra agent instance: new MastraVoiceAgent({ agent: myAgent }).
- Or pass a custom reply function: new MastraVoiceAgent({ generate: async (ctx) => '...' }).
- 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
- Make `agent` or `generate` required in your own wrapper's options type so TypeScript enforces it.
- Beware deserialized configs silently dropping function-valued `generate` options.
- Validate options immediately before construction; fail with a clear message.
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
- @mastra/livekit: MastraVoiceAgent requires `agent` or `gener
- connect({ id, name }): "name" is required when connecting wi
- @mastra/livekit: reply generation runs through the Mastra ag
- @mastra/livekit: MastraLLM requires exactly one reply source
- @mastra/livekit: set exactly one reply generator — `generate
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/00de05d657a129f5.
Report an issue: GitHub.