mastra-ai/mastra · error
@mastra/livekit: MastraVoiceAgent requires `agent` or `gener
Error message
@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`, not both — they are mutually exclusive reply sources.
What it means
MastraVoiceAgent accepts two mutually exclusive reply sources: `agent` (a Mastra agent instance) or `generate` (a custom reply generator function). The constructor throws this error when both are provided, because the bridge cannot decide which one owns reply generation. Exactly one must be supplied.
Source
Thrown at integrations/livekit/src/bridge.ts:439
/**
* A LiveKit `voice.Agent` whose replies come from a Mastra agent or workflow.
*
* LiveKit keeps ownership of the audio loop (VAD, STT, turn detection, TTS, barge-in) and calls
* `llmNode` once per detected user turn; the node delegates to a {@link VoiceReplyGenerator}
* which streams text deltas back. On barge-in LiveKit cancels the returned stream, which aborts
* the in-flight generation.
*/
export class MastraVoiceAgent extends voice.Agent {
readonly mastraAgent?: MastraAgent;
readonly memory: MastraVoiceAgentMemory | false;
readonly requestContext?: RequestContext;
readonly streamOptions?: MastraStreamOptions;
private readonly replyGenerator: VoiceReplyGenerator;
private readonly reminder?: DisclosureReminder;
constructor(options: MastraVoiceAgentOptions) {
if (options.agent && options.generate) {
throw new Error(
'@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`, not both — they are mutually exclusive reply sources.',
);
}
super({
id: options.id,
instructions: options.instructions ?? DEFAULT_INSTRUCTIONS,
stt: options.stt,
vad: options.vad,
llm: new MastraPlaceholderLLM(),
tts: options.tts,
turnHandling: options.turnHandling,
});
this.memory = options.memory ?? false;
this.requestContext = toRequestContext(options.requestContext);
this.streamOptions = options.streamOptions;
if (options.greetingReminder) {
this.reminder = new DisclosureReminder(
options.greetingReminder.everyMs,View on GitHub (pinned to 75dd419e61)
Solutions
- Remove one of the two: keep `agent` for Mastra-agent-driven replies, or keep `generate` for custom replies.
- If migrating from agent to generate, delete the `agent` property from the options object.
- Audit config-building code (object spreads, defaults) so only one reply source is ever set.
Example fix
// before
new MastraVoiceAgent({ agent: myAgent, generate: myFn })
// after
new MastraVoiceAgent({ agent: myAgent }) // or { generate: myFn }, never both Defensive patterns
Strategy: validation
Validate before calling
function assertValidVoiceAgentOptions(o: MastraVoiceAgentOptions): void {
if ('agent' in o && o.agent && 'generate' in o && o.generate) {
throw new Error('MastraVoiceAgent accepts `agent` or `generate`, not both');
}
} Type guard
function hasExactlyOneReplySource(o: MastraVoiceAgentOptions): boolean {
return Boolean(o.agent) !== Boolean(o.generate); // XOR: exactly one present
} Prevention
- Build options objects explicitly instead of spreading partial configs that may carry both keys.
- Centralize MastraVoiceAgent construction in one factory that enforces the XOR constraint.
- When migrating from agent to generate, delete the old key, don't just add the new one.
When it happens
Trigger: new MastraVoiceAgent({ agent, generate, ... }) where both keys are present — typically when merging config objects or adding a custom generate override on top of an existing agent-based config.
Common situations: Spreading defaults ({ ...baseOptions }) that already contain `agent` while adding `generate`; refactoring from agent-based to generate-based replies without removing the old key; conditional config building that accumulates both fields.
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/fc58c979a9821c6a.
Report an issue: GitHub.