{"record":{"id":"51d96feae87db8c0","repo":"mastra-ai/mastra","slug":"start-over-from-the-name-step","errorCode":null,"errorMessage":"Start over from the name step.","messagePattern":"Start over from the name step\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mastracode/factory-ui/src/ui/domains/workspaces/hooks/useCreateFactoryFromDraft.ts","lineNumber":60,"sourceCode":"  // each other's selection.\n  const feedBoard = async (repositorySlug: string, linear?: { sourceId: string; factoryProjectId: string }) => {\n    if (linear) {\n      await saveIntakeBinding.mutateAsync({\n        integrationId: 'linear',\n        sourceId: linear.sourceId,\n        factoryProjectId: linear.factoryProjectId,\n      });\n    }\n    const config = await fetchIntakeConfig(baseUrl);\n    const githubSelection = selectIntakeSource(config.github, repositorySlug);\n    const linearSelection = linear ? selectIntakeSource(config.linear, linear.sourceId) : config.linear;\n    if (githubSelection === config.github && linearSelection === config.linear) return;\n    await saveIntakeConfig.mutateAsync({ ...config, github: githubSelection, linear: linearSelection });\n  };\n\n  return useMutation({\n    mutationFn: async ({ providerId, modelId }: { providerId: string; modelId: string }) => {\n      if (!draft?.name || !draft.repository) throw new Error('Start over from the name step.');\n\n      const factory = draft.factoryId\n        ? { id: draft.factoryId, name: draft.name }\n        : await createFactory.mutateAsync({ name: draft.name });\n      if (!draft.factoryId) await onFactoryCreated(factory);\n\n      if (!draft.linkedRepositoryId) {\n        const linked = await linkRepository.mutateAsync({ factoryProjectId: factory.id, repo: draft.repository });\n        await onRepositoryLinked(linked.projectRepositoryId);\n      }\n\n      const linearPick = draft.linearProjectId\n        ? { sourceId: draft.linearProjectId, factoryProjectId: factory.id }\n        : undefined;\n      await Promise.all([\n        updateFactoryDefaultModel(baseUrl, factory.id, modelId),\n        applyOMDefaults.mutateAsync({ providerId, factoryModelId: modelId, factoryId: factory.id }),\n        feedBoard(draft.repository.fullName, linearPick),","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory-ui/src/ui/domains/workspaces/hooks/useCreateFactoryFromDraft.ts#L42-L78","documentation":"useCreateFactoryFromDraft's mutation throws the literal Error 'Start over from the name step.' when the local draft is missing a name or repository. It is a client-side guard: the factory-creation flow requires those draft fields before it can create (or reuse) the factory, so the hook fails fast and tells the user to return to the first step of the wizard.","triggerScenarios":"Invoking the mutation (createFactory) while the wizard draft has no `name` (user never completed the name step, or draft state was cleared) or no `repository` selected — e.g. deep-linking into a later wizard step, or draft state lost after a page reload.","commonSituations":"User reloads the page and local draft state resets to empty, user navigates directly to the model/provider step via URL, or a bug in the wizard clears `draft.repository` before submission.","solutions":["Return the user to the name step of the creation wizard so the draft gets populated, then retry.","Guard the mutation call site: disable the submit action until `draft?.name && draft?.repository` are set.","Persist the draft (e.g. to sessionStorage/URL) so a reload doesn't wipe name/repository.","If the repository should already be selected, fix the step that sets `draft.repository` to ensure it commits before the final step."],"exampleFix":"// before\ncreateFactory.mutate({ providerId, modelId });\n// after\nif (!draft?.name || !draft?.repository) {\n  goToStep('name');\n  return;\n}\ncreateFactory.mutate({ providerId, modelId });","handlingStrategy":"validation","validationCode":"function canCreateFactory(draft: Draft | null | undefined): draft is Draft & { name: string; repository: string } {\n  return Boolean(draft?.name && draft?.repository);\n}\n// call site\nif (!canCreateFactory(draft)) {\n  goToStep('name');\n  return;\n}","typeGuard":"function draftIsComplete(d: unknown): d is { name: string; repository: string; factoryId?: string } {\n  return typeof d === 'object' && d !== null && typeof (d as any).name === 'string' && (d as any).name.length > 0 && typeof (d as any).repository === 'string' && (d as any).repository.length > 0;\n}","tryCatchPattern":"try {\n  await createFactory.mutateAsync({ providerId, modelId });\n} catch (e) {\n  if ((e as Error).message === 'Start over from the name step.') {\n    resetWizardToNameStep();\n  } else throw e;\n}","preventionTips":["Gate the wizard's final submit button on draft.name && draft.repository being set.","Persist the draft to sessionStorage so page reloads don't clear earlier steps.","Prevent deep-linking past the name step until the draft is complete (step guard in routing).","Ensure the repository-selection step always commits draft.repository before advancing."],"tags":["validation","client-side-guard","wizard-state","react"],"backgroundTag":"missing-required-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}