mastra-ai/mastra · error

Select a repository before starting a Factory run

Error message

Select a repository before starting a Factory run

What it means

Inside useStartFactoryRun, after validating factoryId/workItem, the mutation checks that a repository has been resolved from the factory query (factoryQuery.data?.repositories[0]). If no repository is selected or the factory has no repositories, it throws 'Select a repository before starting a Factory run' because createUserSession(baseUrl, repository.projectRepositoryId, ...) needs a concrete repository id.

Source

Thrown at mastracode/factory-ui/src/hooks/useStartFactoryRun.ts:95

 * The coordinator commits exact authority before it dispatches any message.
 *
 * The run is started in the background: the board stays put and a toast offers
 * the way into the thread once it exists.
 */
export function useStartFactoryRun() {
  const { factoryId } = useParams<{ factoryId: string }>();
  const factoryQuery = useFactoryQuery(factoryId);
  const { baseUrl } = useApiConfig();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const repository = factoryQuery.data?.repositories[0];
  const [phases, setPhases] = useState<Record<string, FactoryRunPhase>>({});

  const mutation = useMutation({
    mutationKey: factoryRunMutationKey(repository?.projectRepositoryId ?? '', factoryId),
    mutationFn: async ({ branch, threadTitle, threadTags, invocation, workItem }: StartFactoryRunInput) => {
      if (!factoryId || !workItem) throw new Error('Factory run requires a board work item');
      if (!repository) throw new Error('Select a repository before starting a Factory run');
      const phaseKey = runPhaseKey({ id: workItem.id, sourceKey: workItem.sourceKey, role: workItem.role });
      const setPhase = (phase: FactoryRunPhase) => setPhases(current => ({ ...current, [phaseKey]: phase }));

      setPhase('workspace');
      const userSession = await createUserSession(baseUrl, repository.projectRepositoryId, { branch });
      const sessionId = userSession.sessionId;
      const desiredStage = workItem.stages.length === 1 ? workItem.stages[0] : undefined;
      if (!isFactoryRuleStage(desiredStage)) throw new Error('Factory runs require one exclusive destination stage');

      setPhase('kickoff');
      const prepared = await startFactoryRun(baseUrl, factoryId, {
        sessionId,
        threadTitle,
        threadTags,
        kickoffKey: crypto.randomUUID(),
        invocation:
          invocation?.type === 'skill'
            ? {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Disable the start/run control until a repository is selected (repository is defined).
  2. Connect at least one repository to the factory project, or show a 'no repositories' state instead of the run button.
  3. Gate on factoryQuery.isSuccess so the run UI only appears after the repository list has loaded.

Example fix

// before
<button onClick={run} />

// after
<button disabled={!repository} onClick={run} />
Defensive patterns

Strategy: validation

Validate before calling

if (!repository) return; // show 'select a repository' state instead

Type guard

const hasRepository = (r: FactoryRepository | undefined): r is FactoryRepository => Boolean(r?.projectRepositoryId);

Try / catch

try { await start(input); } catch (e) { if ((e as Error).message.includes('Select a repository')) focusRepositoryPicker(); }

Prevention

When it happens

Trigger: Calling start() when factoryQuery.data.repositories is empty or repository state hasn't been set — e.g. the factory loads with zero repositories, the repository picker was never interacted with, or the run button was clicked while factoryQuery was still fetching.

Common situations: New factory project with no repositories connected yet; user opened the run dialog before the factory query resolved; a filter/selection change cleared the chosen repository but the run button stayed enabled.

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/2bd4e7cc7c3e4c73. Report an issue: GitHub.