{"record":{"id":"2721c15c0b02236c","repo":"mastra-ai/mastra","slug":"no-factory-selected-2721c1","errorCode":null,"errorMessage":"No Factory selected","messagePattern":"No Factory selected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory-ui/src/hooks/useWorkspaces.ts","lineNumber":191,"sourceCode":"  return useQuery({\n    queryKey: queryKeys.userSession(sessionId),\n    queryFn: sessionId ? () => getUserSession(baseUrl, sessionId) : skipToken,\n  });\n}\n\nexport function useCreateWorkspaceMutation(\n  factoryId: string | undefined,\n  projectRepositoryId: string | undefined,\n  scope?: AgentControllerThreadsScope,\n) {\n  const { baseUrl } = useApiConfig();\n  const queryClient = useQueryClient();\n  const navigate = useNavigate();\n\n  return useMutation({\n    mutationFn: async (branch: string) => {\n      const trimmedBranch = branch.trim();\n      if (!factoryId) throw new Error('No Factory selected');\n      if (!projectRepositoryId) throw new Error('Connect a repository before creating a workspace');\n      return createUserSession(baseUrl, projectRepositoryId, { branch: trimmedBranch });\n    },\n    onSuccess: session => {\n      invalidateSessionQueries(queryClient, projectRepositoryId, scope, session.sessionId);\n      void queryClient.invalidateQueries({ queryKey: queryKeys.userSession(session.sessionId) });\n      void navigate(`/factories/${factoryId}/workspaces/${session.sessionId}`);\n    },\n    onError: error => toast.error(error instanceof Error ? error.message : 'Failed to create workspace'),\n  });\n}\n\nexport function useDeleteWorkspaceMutation(\n  factoryId: string | undefined,\n  projectRepositoryId: string | undefined,\n  scope?: AgentControllerThreadsScope,\n) {\n  const { baseUrl } = useApiConfig();","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory-ui/src/hooks/useWorkspaces.ts#L173-L209","documentation":"useCreateWorkspaceMutation's mutationFn throws 'No Factory selected' when factoryId is undefined at the moment a workspace creation is attempted. Workspaces are always scoped to a Factory, so creating one without that context is rejected before any network call. A companion check ensures a repository is connected first.","triggerScenarios":"Invoking the createWorkspace mutation while factoryId (from route params or factory context) is undefined — e.g. the hook rendered outside a factory route, or before the factory id resolves from the URL/query.","commonSituations":"Navigating to the 'new workspace' flow via a bookmarked URL missing the factory segment; the factory list still loading so no factory is selected; embedding the workspace form in a layout that lacks the FactoryId provider/route param.","solutions":["Render the create-workspace UI only inside the /factories/:factoryId route so useParams provides factoryId.","Disable the create button until factoryId is truthy and show a factory selector otherwise.","If embedding elsewhere, pass factoryId explicitly to the hook instead of relying on route params.","Wait for the factory query to finish loading before exposing the form."],"exampleFix":"// before\nconst createWorkspace = useCreateWorkspaceMutation(factoryId, projectRepositoryId, ...);\n<button onClick={() => createWorkspace.mutate(branch)} /> // throws when factoryId undefined\n\n// after\ndisabled={!factoryId || !projectRepositoryId}\ntitle={factoryId ? undefined : 'Select a Factory first'}","handlingStrategy":"validation","validationCode":"if (!factoryId) {\n  showFactoryPicker();\n  return; // do not call mutation\n}","typeGuard":"function hasFactoryId(id: string | undefined | null): id is string {\n  return typeof id === 'string' && id.length > 0;\n}","tryCatchPattern":"try {\n  await createWorkspace.mutateAsync(branch);\n} catch (e) {\n  if (e instanceof Error && e.message === 'No Factory selected') {\n    toast.error('Select a Factory before creating a workspace');\n  } else throw e;\n}","preventionTips":["Render the create-workspace form only under the factory route.","Keep factoryId in a typed context that refuses to render children without it.","Disable the create button until factoryId resolves."],"tags":["react","react-query","missing-parameter","factory-ui"],"backgroundTag":"missing-required-parameter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}