{"record":{"id":"bfeeb165a07a199e","repo":"mastra-ai/mastra","slug":"factory-runs-require-one-exclusive-destination-sta","errorCode":null,"errorMessage":"Factory runs require one exclusive destination stage","messagePattern":"Factory runs require one exclusive destination stage","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory-ui/src/hooks/useStartFactoryRun.ts","lineNumber":103,"sourceCode":"  const { baseUrl } = useApiConfig();\n  const navigate = useNavigate();\n  const queryClient = useQueryClient();\n  const repository = factoryQuery.data?.repositories[0];\n  const [phases, setPhases] = useState<Record<string, FactoryRunPhase>>({});\n\n  const mutation = useMutation({\n    mutationKey: factoryRunMutationKey(repository?.projectRepositoryId ?? '', factoryId),\n    mutationFn: async ({ branch, threadTitle, threadTags, invocation, workItem }: StartFactoryRunInput) => {\n      if (!factoryId || !workItem) throw new Error('Factory run requires a board work item');\n      if (!repository) throw new Error('Select a repository before starting a Factory run');\n      const phaseKey = runPhaseKey({ id: workItem.id, sourceKey: workItem.sourceKey, role: workItem.role });\n      const setPhase = (phase: FactoryRunPhase) => setPhases(current => ({ ...current, [phaseKey]: phase }));\n\n      setPhase('workspace');\n      const userSession = await createUserSession(baseUrl, repository.projectRepositoryId, { branch });\n      const sessionId = userSession.sessionId;\n      const desiredStage = workItem.stages.length === 1 ? workItem.stages[0] : undefined;\n      if (!isFactoryRuleStage(desiredStage)) throw new Error('Factory runs require one exclusive destination stage');\n\n      setPhase('kickoff');\n      const prepared = await startFactoryRun(baseUrl, factoryId, {\n        sessionId,\n        threadTitle,\n        threadTags,\n        kickoffKey: crypto.randomUUID(),\n        invocation:\n          invocation?.type === 'skill'\n            ? {\n                ...invocation,\n                arguments: `${invocation.arguments.trim()}\\n\\nPrepared workspace context:\\n- Session: ${sessionId}\\n- Branch: ${userSession.branch}`,\n              }\n            : invocation,\n        destinationStage: desiredStage,\n        workItem: {\n          id: workItem.id,\n          role: workItem.role,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory-ui/src/hooks/useStartFactoryRun.ts#L85-L121","documentation":"useStartFactoryRun derives the destination stage as `workItem.stages.length === 1 ? workItem.stages[0] : undefined` and then validates it with isFactoryRuleStage(desiredStage). Factory runs must target exactly one recognized rule stage; if the work item has zero, multiple, or an unrecognized stage, the mutation throws 'Factory runs require one exclusive destination stage' before calling startFactoryRun.","triggerScenarios":"Starting a run for a workItem whose stages array has length != 1, or whose single stage fails the isFactoryRuleStage check (wrong/legacy stage name) — e.g. a board item configured for multiple destination stages, or stage taxonomy changed server-side.","commonSituations":"Work item configured in the board UI with several target stages; stale board data after a stage was renamed/removed so the item's stage string no longer matches the rule-stage union; importing work items from an integration that assigns multiple stages.","solutions":["Edit the board work item so it has exactly one destination stage that matches a valid factory rule stage.","Refresh the board/work item data to clear stale stage names after a taxonomy change.","Update isFactoryRuleStage (or the stage enum) if a new legitimate stage type was introduced but not added to the union."],"exampleFix":"// before\nstart({ workItem }); // workItem.stages = ['review', 'deploy']\n\n// after\nconst runnable = workItem.stages.length === 1 && isFactoryRuleStage(workItem.stages[0]);\nif (runnable) start({ workItem });","handlingStrategy":"validation","validationCode":"const stage = workItem?.stages.length === 1 ? workItem.stages[0] : undefined;\nif (!isFactoryRuleStage(stage)) return; // block start, prompt user to fix stages","typeGuard":"function isFactoryRuleStage(s: unknown): s is FactoryRuleStage {\n  return typeof s === 'string' && RULE_STAGES.includes(s as FactoryRuleStage);\n}","tryCatchPattern":"try { await start(input); } catch (e) { if ((e as Error).message.includes('exclusive destination stage')) openStageEditor(workItem); }","preventionTips":["Enforce single-stage configuration in the board editor UI.","Keep the stage union in sync with server-side stage taxonomy.","Refresh board data after any stage rename/removal."],"tags":["guard-clause","validation","factory-ui","domain-rules"],"backgroundTag":"invalid-stage-configuration","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}