BloopAI/vibe-kanban · warning · Error

Machine client is required

Error message

Machine client is required

What it means

The repos useQuery in ReposSettingsSection has a queryFn that throws 'Machine client is required' if machineClient is null when react-query invokes it. This is a defensive guard: the query is disabled (enabled: machineClient != null), so the throw fires only if the query runs while the client became null (or during refetch after the machine was unselected).

Source

Thrown at packages/web-core/src/shared/dialogs/settings/settings/ReposSettingsSection.tsx:150

}: ReposSettingsSectionProps) {
  const { t } = useTranslation('settings');
  const queryClient = useQueryClient();
  const machineClient = useSettingsMachineClient();
  const reposQueryKey = [
    'repos',
    ...(machineClient?.queryScopeKey ?? ['machine', 'unselected']),
  ] as const;

  // Fetch all repos
  const {
    data: repos,
    isLoading: reposLoading,
    error: reposError,
  } = useQuery({
    queryKey: reposQueryKey,
    queryFn: () => {
      if (!machineClient) {
        throw new Error('Machine client is required');
      }

      return machineClient.listRepos();
    },
    enabled: machineClient != null,
  });

  // Selected repo state - initialize from props if provided
  const [selectedRepoId, setSelectedRepoId] = useState<string>(
    initialState?.repoId ?? ''
  );

  // Fetch branches for the selected repo
  const { data: branches = [], isLoading: branchesLoading } =
    useMachineRepoBranches(machineClient, selectedRepoId || null, {
      enabled: !!selectedRepoId,
    });

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Re-select the machine so the query re-enables and refetches successfully
  2. Clear the query error by remounting the section with a live machineClient
  3. Keep machineClient in the queryKey/query scope (it already is via queryScopeKey) so null-state changes produce a fresh disabled query instead of a stale refetch
  4. Optionally narrow enabled to a boolean check that stays false during transitions (enabled: machineClient != null) and null out queryFn otherwise

Example fix

// before
queryFn: () => {
  if (!machineClient) {
    throw new Error('Machine client is required');
  }
  return machineClient.listRepos();
},
// after
queryFn: (ctx) => ctx.queryClient.fetchQuery({
  queryKey: ['repos', machineClient!.queryScopeKey],
  queryFn: () => machineClient!.listRepos(),
}), // machineClient non-null asserted because enabled: machineClient != null
Defensive patterns

Strategy: type-guard

Validate before calling

// keep the query off while no client exists:
const enabled = machineClient != null;
useQuery({ queryKey: reposQueryKey, queryFn, enabled });

Type guard

function isNonNull<T>(v: T | null | undefined): v is T {
  return v != null;
}

Try / catch

const { data, error } = useQuery({
  queryKey: reposQueryKey,
  queryFn: () => machineClient ? machineClient.listRepos() : Promise.reject(new Error('Machine client is required')),
  enabled: isNonNull(machineClient),
  retry: false, // a null-client guard is not transient; surface it immediately
});
if (error?.message === 'Machine client is required') return <MachinePickerPrompt />;

Prevention

When it happens

Trigger: react-query executes queryFn (mount with enabled momentarily true, or refetch triggered while machineClient transitions to null) and the closure observes machineClient == null; the error becomes the query's `error` state (reposError).

Common situations: Machine unselected/disconnected while the repos list refetch ran; strict-mode double invocation races; component remounted in a context without a machine client.

Related errors


AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29). Data as JSON: /api/errors/d12babfeced7cb11. Report an issue: GitHub.