BloopAI/vibe-kanban · error · Error

Machine client is required

Error message

Machine client is required

What it means

SettingsMachineUserSystemProvider builds config load/save callbacks around an optional `machineClient` prop. `loadConfig` is a stable callback that must return `machineClient.getConfig()`, so when the client is absent (null/undefined) it throws 'Machine client is required' rather than returning a rejected promise. This is an intentional programming-error guard: the settings dialog should never be mounted without a machine client.

Source

Thrown at packages/web-core/src/shared/dialogs/settings/settings/SettingsMachineUserSystemProvider.tsx:25

  children,
}: {
  children: ReactNode;
}) {
  const machineClient = useSettingsMachineClient();
  const queryKey = useMemo(() => {
    if (machineClient?.target.kind === 'local') {
      return ['user-system', 'local'] as const;
    }

    return [
      'user-system',
      'settings-machine',
      machineClient?.target.id ?? 'unselected',
    ] as const;
  }, [machineClient]);
  const loadConfig = useCallback(() => {
    if (!machineClient) {
      throw new Error('Machine client is required');
    }

    return machineClient.getConfig();
  }, [machineClient]);
  const saveConfig = useCallback(
    (
      config: Parameters<NonNullable<typeof machineClient>['saveConfig']>[0]
    ) => {
      if (!machineClient) {
        throw new Error('Machine client is required');
      }

      return machineClient.saveConfig(config);
    },
    [machineClient]
  );

  const { value } = useUserSystemController({

View on GitHub (pinned to 4deb7eca8f)

Solutions

  1. Do not render SettingsMachineUserSystemProvider until machineClient is defined (guard in the parent: `{machineClient && <SettingsMachineUserSystemProvider machineClient={machineClient}/>}`).
  2. In a hook consumer, check `machineClient` before calling loadConfig/saveConfig and skip/return early.
  3. If the client loads asynchronously, show a loading state while it is undefined instead of mounting the provider.

Example fix

// before
<SettingsMachineUserSystemProvider machineClient={machineClient} />
// after
{machineClient ? (
  <SettingsMachineUserSystemProvider machineClient={machineClient} />
) : (
  <Spinner />
)}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!machineClient) {
  // render loading state or skip mounting the provider
  return <Spinner />;
}

Try / catch

try {
  const config = loadConfig();
} catch (err) {
  if (err instanceof Error && err.message === 'Machine client is required') {
    // machineClient not ready — wait or re-render when it resolves
  }
}

Prevention

When it happens

Trigger: Rendering SettingsMachineUserSystemProvider without a machineClient prop (or with undefined while machine data is still loading) and then invoking the config-loading path, e.g. via useMachineUserSystem/useConfig hooks that call loadConfig().

Common situations: Opening the machine settings dialog before the machine client hook has resolved; a parent conditionally rendering the provider too early; a refactor renaming/removing the machineClient prop while defaults swallow it.

Related errors


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