{"record":{"id":"615e5a8f6531ce87","repo":"mastra-ai/mastra","slug":"mastra-livekit-set-agent-or-workflow-not-bo","errorCode":null,"errorMessage":"@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.","messagePattern":"@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/livekit/src/worker.ts","lineNumber":788,"sourceCode":" *   mastra,\n *   stt: 'deepgram/nova-3',\n *   tts: 'cartesia/sonic-3',\n *   turnDetection: 'multilingual',\n * });\n *\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n *   runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' });\n * }\n * ```\n */\nexport function createLiveKitWorker(options: CreateLiveKitWorkerOptions) {\n  if (options.generate && (options.agent || options.workflow)) {\n    throw new Error(\n      '@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.',\n    );\n  }\n  if (options.agent && options.workflow) {\n    throw new Error(\n      '@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.',\n    );\n  }\n  if (options.workflow && !options.workflowInput) {\n    throw new Error(\n      '@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the ' +\n        'workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).',\n    );\n  }\n  if (options.generate && options.configuration?.endCall) {\n    throw new Error(\n      '@mastra/livekit: `configuration.endCall` has no effect with `generate` — the worker cannot observe ' +\n        'tool calls from a custom reply generator. Detect the end-call tool inside your generator and call ' +\n        '`runEndCall` directly instead.',\n    );\n  }\n\n  const wantsSileroVad = options.vad === undefined || options.vad === 'silero';","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/integrations/livekit/src/worker.ts#L770-L806","documentation":"`agent` and `workflow` are both reply generators for the LiveKit worker and cannot be combined. If both are set, the worker cannot determine which one should handle each turn, so it throws immediately during worker creation.","triggerScenarios":"createLiveKitWorker({ agent: someAgent, workflow: someWorkflow }) — both options defined, with or without `generate`.","commonSituations":"Migrating a voice pipeline from agents to workflows while both fields linger; a generic factory that blindly assigns all configured handlers to options; copying sample code that mentions both options.","solutions":["Remove either `agent` or `workflow`, keeping the one you want to run.","If you genuinely need both behaviors, route internally: e.g. run the workflow inside the `generate` callback so only one generator option is set."],"exampleFix":"// before\ncreateLiveKitWorker({ agent: myAgent, workflow: myWorkflow });\n// after\ncreateLiveKitWorker({ workflow: myWorkflow, workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }) });","handlingStrategy":"validation","validationCode":"if (options.agent && options.workflow) throw new Error('Choose either agent or workflow, not both, before creating the LiveKit worker');","typeGuard":"function hasExclusiveReplyHandler(o: { agent?: unknown; workflow?: unknown }): boolean {\n  return !(o.agent != null && o.workflow != null);\n}","tryCatchPattern":"try {\n  const worker = createLiveKitWorker(options);\n} catch (e) {\n  if ((e as Error).message.includes('mutually exclusive reply generators')) {\n    console.error('Set either agent or workflow, not both');\n  } else throw e;\n}","preventionTips":["Use a discriminated union option type keyed on the generator kind","If you need agent+workflow behavior, wrap the workflow inside a single generate callback","Keep one source of truth for reply handling in config files"],"tags":["configuration","validation","livekit","worker"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}