mastra-ai/mastra · error

Factory project is required

Error message

Factory project is required

What it means

useFactoryDecisionAction wraps actOnFactoryDecision(baseUrl, githubProjectId, decisionId, action) to release, dismiss, or requeue a queued factory effect. Because githubProjectId is typed `string | undefined`, the mutationFn guards with 'Factory project is required' before issuing the request. The library throws rather than sending a malformed request to the decisions endpoint.

Source

Thrown at mastracode/factory-ui/src/hooks/useFactoryDecisions.ts:30

export function useFactoryDecisionStatus(githubProjectId: string | undefined, statuses: FactoryDecisionStatus[]) {
  const { baseUrl } = useApiConfig();
  const statusKey = statuses.join(',');
  return useQuery({
    queryKey: queryKeys.factoryDecisions(githubProjectId, statusKey),
    queryFn: () => fetchFactoryDecisions(baseUrl, githubProjectId!, { statuses, limit: 50 }),
    enabled: Boolean(githubProjectId),
    refetchInterval: 2_000,
    staleTime: 1_000,
  });
}

/** Release, turn down, or requeue one queued effect. */
export function useFactoryDecisionAction(githubProjectId: string | undefined, action: FactoryDecisionAction) {
  const { baseUrl } = useApiConfig();
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (decisionId: string) => {
      if (!githubProjectId) throw new Error('Factory project is required');
      return actOnFactoryDecision(baseUrl, githubProjectId, decisionId, action);
    },
    onSuccess: async () => {
      await Promise.all([
        queryClient.invalidateQueries({ queryKey: queryKeys.factoryDecisionsRoot(githubProjectId) }),
        queryClient.invalidateQueries({ queryKey: queryKeys.factoryAttentionRoot(githubProjectId) }),
      ]);
    },
  });
}

export function useFactoryDecisionHistory(
  githubProjectId: string | undefined,
  statusKey: string,
  statuses: FactoryDecisionStatus[] | undefined,
) {
  const { baseUrl } = useApiConfig();
  return useInfiniteQuery({

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure the action buttons are disabled until githubProjectId is defined, or conditionally render the decision list only after the project resolves.
  2. Verify the call site passes the correct variable (githubProjectId vs a similarly named project/factory id) into useFactoryDecisionAction.
  3. If actions can legitimately occur without a project, restructure so the mutation is only created once the id exists (e.g. inside a child component mounted under a loaded route).

Example fix

// before
const { dismiss } = useFactoryDecisionAction(projectId, 'dismiss');
<button onClick={() => dismiss(id)} />

// after
const { dismiss } = useFactoryDecisionAction(projectId, 'dismiss');
<button disabled={!projectId} onClick={() => projectId && dismiss(id)} />
Defensive patterns

Strategy: validation

Validate before calling

if (!githubProjectId) return; // do not render or invoke decision actions

Type guard

const hasProject = (id: string | undefined): id is string => typeof id === 'string' && id.length > 0;

Try / catch

mutation.mutate(decisionId, { onError: err => { if ((err as Error).message === 'Factory project is required') showToast('Project not loaded yet'); } });

Prevention

When it happens

Trigger: Invoking any of retryDecision, approve, dismiss, retry, approveDecision, or dismissDecision while githubProjectId is undefined — e.g. the component mounted before the project selection resolved, or the id prop was dropped when wiring the hook.

Common situations: Decision list rendered from a query that hasn't resolved its parent project yet; a rename/refactor changed the prop so the hook now receives undefined; clicking an action button on a card before project context loads in a deeply nested route.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/70313a411e4d2ea3. Report an issue: GitHub.