{"record":{"id":"eb16b1cf7ba6dda2","repo":"Crosstalk-Solutions/project-nomad","slug":"failed-to-start-update","errorCode":null,"errorMessage":"Failed to start update","messagePattern":"Failed to start update","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"admin/inertia/pages/settings/update.tsx","lineNumber":129,"sourceCode":"        // During container restart, we'll lose connection - this is expected\n        // Show a notice to inform the user that this is normal\n        setShowConnectionLostNotice(true)\n        // Continue polling to detect when the container comes back up\n        console.log('Polling update status (container may be restarting)...')\n      }\n    }, 2000)\n\n    return () => clearInterval(interval)\n  }, [isUpdating])\n\n  const handleStartUpdate = async () => {\n    try {\n      setError(null)\n      seenAdvancedStageRef.current = false\n      setIsUpdating(true)\n      const response = await api.startSystemUpdate()\n      if (!response || !response.success) {\n        throw new Error('Failed to start update')\n      }\n    } catch (err: any) {\n      setIsUpdating(false)\n      setError(err.response?.data?.error || err.message || 'Failed to start update')\n    }\n  }\n\n  const handleViewLogs = async () => {\n    try {\n      const response = await api.getSystemUpdateLogs()\n      if (!response) {\n        throw new Error('Failed to fetch update logs')\n      }\n      setLogs(response.logs)\n      setShowLogs(true)\n    } catch (err) {\n      setError('Failed to fetch update logs')\n    }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/Crosstalk-Solutions/project-nomad/blob/0bd1c6f4f9888d577fe232de06ac144bb8337131/admin/inertia/pages/settings/update.tsx#L111-L147","documentation":"Raised in handleStartUpdate when api.startSystemUpdate() resolves falsy or with success !== true, or when the request itself rejects. The catch block normalizes the error to err.response?.data?.error || err.message || 'Failed to start update'.","triggerScenarios":"POST to start the system update rejected: another update already running (409), insufficient disk space, missing update manifest, or the update service not enabled on this build.","commonSituations":"Double-clicking the Update button firing two requests, admin session expired so middleware returns a redirect/HTML login page, or the update channel not configured on dev builds.","solutions":["Check the response body's error field (already surfaced via setError) and the backend update-controller logs","Disable the button while isUpdating to prevent duplicate submissions","Verify an update manifest/channel is configured and disk space is sufficient","Ensure the API client follows redirects and surfaces JSON errors, not silent HTML"],"exampleFix":"// before\nconst response = await api.startSystemUpdate()\nif (!response || !response.success) {\n  throw new Error('Failed to start update')\n}\n// after\nconst response = await api.startSystemUpdate()\nif (!response?.success) {\n  throw new Error(response?.error || 'Failed to start update')\n}","handlingStrategy":"try-catch","validationCode":"if (isUpdating || !canStart) return","typeGuard":null,"tryCatchPattern":"try {\n  const r = await api.startSystemUpdate()\n  if (!r?.success) throw new Error(r?.error || 'Failed to start update')\n} catch (err: any) {\n  setIsUpdating(false)\n  setError(err.response?.data?.error || err.message || 'Failed to start update')\n}","preventionTips":["Disable the start button while isUpdating to prevent double submissions","Surface server error fields over the generic fallback","Confirm auth session validity before long operations"],"tags":["system-update","frontend","admin-ui"],"backgroundTag":"operation-start-rejected","analyzedSha":"0bd1c6f4f9888d577fe232de06ac144bb8337131","analyzedAt":"2026-08-27T05:34:15.424Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}