{"record":{"id":"d12babfeced7cb11","repo":"BloopAI/vibe-kanban","slug":"machine-client-is-required-d12bab","errorCode":null,"errorMessage":"Machine client is required","messagePattern":"Machine client is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/web-core/src/shared/dialogs/settings/settings/ReposSettingsSection.tsx","lineNumber":150,"sourceCode":"}: ReposSettingsSectionProps) {\n  const { t } = useTranslation('settings');\n  const queryClient = useQueryClient();\n  const machineClient = useSettingsMachineClient();\n  const reposQueryKey = [\n    'repos',\n    ...(machineClient?.queryScopeKey ?? ['machine', 'unselected']),\n  ] as const;\n\n  // Fetch all repos\n  const {\n    data: repos,\n    isLoading: reposLoading,\n    error: reposError,\n  } = useQuery({\n    queryKey: reposQueryKey,\n    queryFn: () => {\n      if (!machineClient) {\n        throw new Error('Machine client is required');\n      }\n\n      return machineClient.listRepos();\n    },\n    enabled: machineClient != null,\n  });\n\n  // Selected repo state - initialize from props if provided\n  const [selectedRepoId, setSelectedRepoId] = useState<string>(\n    initialState?.repoId ?? ''\n  );\n\n  // Fetch branches for the selected repo\n  const { data: branches = [], isLoading: branchesLoading } =\n    useMachineRepoBranches(machineClient, selectedRepoId || null, {\n      enabled: !!selectedRepoId,\n    });\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/dialogs/settings/settings/ReposSettingsSection.tsx#L132-L168","documentation":"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).","triggerScenarios":"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).","commonSituations":"Machine unselected/disconnected while the repos list refetch ran; strict-mode double invocation races; component remounted in a context without a machine client.","solutions":["Re-select the machine so the query re-enables and refetches successfully","Clear the query error by remounting the section with a live machineClient","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","Optionally narrow enabled to a boolean check that stays false during transitions (enabled: machineClient != null) and null out queryFn otherwise"],"exampleFix":"// before\nqueryFn: () => {\n  if (!machineClient) {\n    throw new Error('Machine client is required');\n  }\n  return machineClient.listRepos();\n},\n// after\nqueryFn: (ctx) => ctx.queryClient.fetchQuery({\n  queryKey: ['repos', machineClient!.queryScopeKey],\n  queryFn: () => machineClient!.listRepos(),\n}), // machineClient non-null asserted because enabled: machineClient != null","handlingStrategy":"type-guard","validationCode":"// keep the query off while no client exists:\nconst enabled = machineClient != null;\nuseQuery({ queryKey: reposQueryKey, queryFn, enabled });","typeGuard":"function isNonNull<T>(v: T | null | undefined): v is T {\n  return v != null;\n}","tryCatchPattern":"const { data, error } = useQuery({\n  queryKey: reposQueryKey,\n  queryFn: () => machineClient ? machineClient.listRepos() : Promise.reject(new Error('Machine client is required')),\n  enabled: isNonNull(machineClient),\n  retry: false, // a null-client guard is not transient; surface it immediately\n});\nif (error?.message === 'Machine client is required') return <MachinePickerPrompt />;","preventionTips":["Never enable machine-scoped queries without a client (enabled: machineClient != null)","Include the client's queryScopeKey in the queryKey so client changes create fresh queries","Handle the query's error state with a 'select a machine' empty state rather than crashing","Avoid refetch-on-focus for machine-bound queries to reduce null-window refetches"],"tags":["react-query","guard","client-init"],"backgroundTag":"missing-machine-client","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}