mastra-ai/mastra · warning
Start over from the name step.
Error message
Start over from the name step.
What it means
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.
Source
Thrown at mastracode/factory-ui/src/ui/domains/workspaces/hooks/useCreateFactoryFromDraft.ts:60
// each other's selection.
const feedBoard = async (repositorySlug: string, linear?: { sourceId: string; factoryProjectId: string }) => {
if (linear) {
await saveIntakeBinding.mutateAsync({
integrationId: 'linear',
sourceId: linear.sourceId,
factoryProjectId: linear.factoryProjectId,
});
}
const config = await fetchIntakeConfig(baseUrl);
const githubSelection = selectIntakeSource(config.github, repositorySlug);
const linearSelection = linear ? selectIntakeSource(config.linear, linear.sourceId) : config.linear;
if (githubSelection === config.github && linearSelection === config.linear) return;
await saveIntakeConfig.mutateAsync({ ...config, github: githubSelection, linear: linearSelection });
};
return useMutation({
mutationFn: async ({ providerId, modelId }: { providerId: string; modelId: string }) => {
if (!draft?.name || !draft.repository) throw new Error('Start over from the name step.');
const factory = draft.factoryId
? { id: draft.factoryId, name: draft.name }
: await createFactory.mutateAsync({ name: draft.name });
if (!draft.factoryId) await onFactoryCreated(factory);
if (!draft.linkedRepositoryId) {
const linked = await linkRepository.mutateAsync({ factoryProjectId: factory.id, repo: draft.repository });
await onRepositoryLinked(linked.projectRepositoryId);
}
const linearPick = draft.linearProjectId
? { sourceId: draft.linearProjectId, factoryProjectId: factory.id }
: undefined;
await Promise.all([
updateFactoryDefaultModel(baseUrl, factory.id, modelId),
applyOMDefaults.mutateAsync({ providerId, factoryModelId: modelId, factoryId: factory.id }),
feedBoard(draft.repository.fullName, linearPick),View on GitHub (pinned to 75dd419e61)
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.
Example fix
// before
createFactory.mutate({ providerId, modelId });
// after
if (!draft?.name || !draft?.repository) {
goToStep('name');
return;
}
createFactory.mutate({ providerId, modelId }); Defensive patterns
Strategy: validation
Validate before calling
function canCreateFactory(draft: Draft | null | undefined): draft is Draft & { name: string; repository: string } {
return Boolean(draft?.name && draft?.repository);
}
// call site
if (!canCreateFactory(draft)) {
goToStep('name');
return;
} Type guard
function draftIsComplete(d: unknown): d is { name: string; repository: string; factoryId?: string } {
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;
} Try / catch
try {
await createFactory.mutateAsync({ providerId, modelId });
} catch (e) {
if ((e as Error).message === 'Start over from the name step.') {
resetWizardToNameStep();
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- ClaudeSDKAgent resumeData must include sessionId or continue
- CursorSDKAgent resumeData must include a message.
- CursorSDKAgent resumeData.agentId must be a string when prov
- CursorSDKAgent does not support structuredOutput because the
- OpenAISDKAgent resumeData must include a message.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/51d96feae87db8c0.
Report an issue: GitHub.