{"record":{"id":"606e8d329c6e378f","repo":"mastra-ai/mastra","slug":"mastra-livekit-workflowinput-is-required-when","errorCode":null,"errorMessage":"@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).","messagePattern":"@mastra/livekit: `workflowInput` is required when `workflow` is set\\. Map the turn into the workflow inputData, e\\.g\\. workflowInput: \\((.+?)\\) => \\((.+?)\\)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/livekit/src/worker.ts","lineNumber":793,"sourceCode":" *\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';\n\n  // The turn detector's inference runners register at plugin-import time, and the agent\n  // server only spawns its inference process for runners registered before it starts —\n  // so begin the import now (worker definition happens at module scope, before\n  // runLiveKitWorker boots the server, which awaits this).","sourceCodeStart":775,"sourceCodeEnd":811,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/integrations/livekit/src/worker.ts#L775-L811","documentation":"When `workflow` is the reply generator, the worker needs a `workflowInput` mapper to turn the LiveKit chat context into the workflow's inputData schema; without it the workflow would receive no input and fail. The library therefore requires `workflowInput` whenever `workflow` is set.","triggerScenarios":"createLiveKitWorker({ workflow: myWorkflow }) with options.workflowInput undefined — the guard `options.workflow && !options.workflowInput` fires.","commonSituations":"Building a workflow-based voice agent and missing the required companion option; converting a sample that used `agent` (no input mapper needed) to `workflow`; TypeScript types bypassed via `as` casts or loose typing.","solutions":["Add a workflowInput function that maps ({ chatCtx }) to the workflow inputData, e.g. ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).","Match the returned object to the workflow's zod input schema field names exactly."],"exampleFix":"// before\ncreateLiveKitWorker({ workflow: myWorkflow });\n// after\ncreateLiveKitWorker({\n  workflow: myWorkflow,\n  workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }),\n});","handlingStrategy":"validation","validationCode":"if (options.workflow && !options.workflowInput) throw new Error('workflowInput is required when workflow is set');","typeGuard":"function workflowOptionsValid(o: { workflow?: unknown; workflowInput?: unknown }): boolean {\n  return o.workflow == null || typeof o.workflowInput === 'function';\n}","tryCatchPattern":"try {\n  const worker = createLiveKitWorker(options);\n} catch (e) {\n  if ((e as Error).message.includes('workflowInput is required')) {\n    console.error('Add workflowInput: ({ chatCtx }) => ({ ... }) matching your workflow input schema');\n  } else throw e;\n}","preventionTips":["Always pair workflow with a workflowInput mapper derived from the workflow's zod input schema","Validate the workflowInput return shape against the input schema in a unit test","Reuse a shared helper like chatContextToMessages instead of ad-hoc mappers"],"tags":["configuration","livekit","workflow","validation"],"backgroundTag":"missing-required-option","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}