{"record":{"id":"c7baa903be203ef8","repo":"Crosstalk-Solutions/project-nomad","slug":"failed-to-dispatch-update-check-c7baa9","errorCode":null,"errorMessage":"Failed to dispatch update check","messagePattern":"Failed to dispatch update check","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"admin/inertia/pages/supply-depot.tsx","lineNumber":287,"sourceCode":"    setOpenDropdown(null)\n    setLoading(true)\n    const result = await api.updateCustomAppImage(service.service_name)\n    setLoading(false)\n    if (!result?.success) showError(result?.message || 'Failed to update app.')\n    else setTimeout(() => window.location.reload(), 1500)\n  }\n\n  // Manual trigger for the catalog-wide update check. Results stream back over the\n  // SERVICE_UPDATES broadcast (handled by the effect above), which reloads the page.\n  async function handleCheckUpdates() {\n    if (!isOnline) {\n      showError('You must have an internet connection to check for updates.')\n      return\n    }\n    try {\n      setCheckingUpdates(true)\n      const response = await api.checkServiceUpdates()\n      if (!response?.success) throw new Error(response?.message || 'Failed to dispatch update check')\n    } catch (error: any) {\n      showError(`Failed to check for updates: ${error?.message || 'Unknown error'}`)\n      setCheckingUpdates(false)\n    }\n  }\n\n  // Versioned update for a curated (non-custom) catalog app. Progress + reload are handled\n  // by the installActivity effect (update-complete) above.\n  async function handleUpdateService(service: ServiceSlim, targetVersion: string) {\n    setLoading(true)\n    const result = await api.updateService(service.service_name, targetVersion)\n    setLoading(false)\n    if (!result?.success) showError(result?.message || 'Failed to update service.')\n  }\n\n  // Toggle per-app automatic updates (opt-in). Optimistically reflects the new\n  // state, reverting if the request fails. Gated by the global master switch in\n  // Settings → Updates; this only sets the per-app preference.","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/Crosstalk-Solutions/project-nomad/blob/0bd1c6f4f9888d577fe232de06ac144bb8337131/admin/inertia/pages/supply-depot.tsx#L269-L305","documentation":"Thrown by handleCheckUpdates on the supply-depot page when api.checkServiceUpdates() resolves with success !== true (or falsy). The surrounding catch converts it to a toast 'Failed to check for updates: ...'.","triggerScenarios":"POST/GET to check service updates rejected by the backend: the update-check job is already queued, the depot service is unreachable, or the admin token is invalid so an interceptor returns undefined.","commonSituations":"Clicking Check Updates while a previous check is still running, appliance without internet (there is a pre-check but it can be wrong), or expired session mid-flight.","solutions":["Look at the toast's embedded message and backend logs for why the check was rejected","Disable the button while checkingUpdates is true to avoid double dispatch","Confirm internet connectivity check passes and the depot endpoint is reachable","Ensure the API wrapper surfaces server-provided message fields"],"exampleFix":"// before\nif (!response?.success) throw new Error(response?.message || 'Failed to dispatch update check')\n// after\nif (!response?.success) throw new Error(response?.message || response?.error || 'Failed to dispatch update check')","handlingStrategy":"try-catch","validationCode":"if (checkingUpdates) return","typeGuard":null,"tryCatchPattern":"try {\n  setCheckingUpdates(true)\n  const r = await api.checkServiceUpdates()\n  if (!r?.success) throw new Error(r?.message || 'Failed to dispatch update check')\n} catch (error: any) {\n  showError(`Failed to check for updates: ${error?.message || 'Unknown error'}`)\n} finally {\n  setCheckingUpdates(false)\n}","preventionTips":["Disable the check button while checkingUpdates is true","Verify online status before dispatching","Include server message/error fields in the thrown error"],"tags":["supply-depot","updates","frontend"],"backgroundTag":"job-already-dispatched","analyzedSha":"0bd1c6f4f9888d577fe232de06ac144bb8337131","analyzedAt":"2026-08-27T05:34:15.424Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}