mastra-ai/mastra · error

@mastra/livekit: set exactly one reply generator — `generate

Error message

@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.

What it means

createLiveKitWorker accepts three mutually exclusive ways to produce a voice reply: `generate` (custom generator), `agent` (Mastra agent), or `workflow` (Mastra workflow). The library throws this when `generate` is set together with `agent` and/or `workflow`, because it cannot decide which generator to run. Exactly one reply generator must be configured.

Source

Thrown at integrations/livekit/src/worker.ts:783

 * import { fileURLToPath } from 'node:url';
 * import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker';
 * import { mastra } from './index';
 *
 * export default createLiveKitWorker({
 *   mastra,
 *   stt: 'deepgram/nova-3',
 *   tts: 'cartesia/sonic-3',
 *   turnDetection: 'multilingual',
 * });
 *
 * if (process.argv[1] === fileURLToPath(import.meta.url)) {
 *   runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' });
 * }
 * ```
 */
export function createLiveKitWorker(options: CreateLiveKitWorkerOptions) {
  if (options.generate && (options.agent || options.workflow)) {
    throw new Error(
      '@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.',
    );
  }
  if (options.agent && options.workflow) {
    throw new Error(
      '@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.',
    );
  }
  if (options.workflow && !options.workflowInput) {
    throw new Error(
      '@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the ' +
        'workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).',
    );
  }
  if (options.generate && options.configuration?.endCall) {
    throw new Error(
      '@mastra/livekit: `configuration.endCall` has no effect with `generate` — the worker cannot observe ' +
        'tool calls from a custom reply generator. Detect the end-call tool inside your generator and call ' +

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Keep only one reply generator: delete `generate` if you now use `agent` or `workflow` (or vice versa).
  2. If you need custom logic plus an agent/workflow, move that logic into the `generate` function itself or into the workflow steps, keeping a single option.

Example fix

// before
createLiveKitWorker({ generate: myGenerate, agent: myAgent });
// after
createLiveKitWorker({ agent: myAgent });
Defensive patterns

Strategy: validation

Validate before calling

const generatorCount = [!!options.generate, !!options.agent, !!options.workflow].filter(Boolean).length;
if (generatorCount !== 1) throw new Error('configure exactly one of generate/agent/workflow before creating the worker');

Type guard

function hasSingleGenerator(o: { generate?: unknown; agent?: unknown; workflow?: unknown }): boolean {
  return [o.generate, o.agent, o.workflow].filter(v => v != null).length === 1;
}

Try / catch

try {
  const worker = createLiveKitWorker(options);
} catch (e) {
  if ((e as Error).message.includes('exactly one reply generator')) {
    console.error('Fix worker config: keep only one of generate/agent/workflow');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling createLiveKitWorker({ generate: ..., agent: someAgent }) or createLiveKitWorker({ generate: ..., workflow: someWorkflow }) — any combination where options.generate && (options.agent || options.workflow).

Common situations: Migrating from the `generate` callback to a higher-level `agent` option but forgetting to delete `generate`; copying a sample config that sets both; spreading two partial option objects into one worker config.

Related errors


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