Crosstalk-Solutions/project-nomad · warning
Failed to dispatch update check
Error message
Failed to dispatch update check
What it means
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: ...'.
Source
Thrown at admin/inertia/pages/supply-depot.tsx:287
setOpenDropdown(null)
setLoading(true)
const result = await api.updateCustomAppImage(service.service_name)
setLoading(false)
if (!result?.success) showError(result?.message || 'Failed to update app.')
else setTimeout(() => window.location.reload(), 1500)
}
// Manual trigger for the catalog-wide update check. Results stream back over the
// SERVICE_UPDATES broadcast (handled by the effect above), which reloads the page.
async function handleCheckUpdates() {
if (!isOnline) {
showError('You must have an internet connection to check for updates.')
return
}
try {
setCheckingUpdates(true)
const response = await api.checkServiceUpdates()
if (!response?.success) throw new Error(response?.message || 'Failed to dispatch update check')
} catch (error: any) {
showError(`Failed to check for updates: ${error?.message || 'Unknown error'}`)
setCheckingUpdates(false)
}
}
// Versioned update for a curated (non-custom) catalog app. Progress + reload are handled
// by the installActivity effect (update-complete) above.
async function handleUpdateService(service: ServiceSlim, targetVersion: string) {
setLoading(true)
const result = await api.updateService(service.service_name, targetVersion)
setLoading(false)
if (!result?.success) showError(result?.message || 'Failed to update service.')
}
// Toggle per-app automatic updates (opt-in). Optimistically reflects the new
// state, reverting if the request fails. Gated by the global master switch in
// Settings → Updates; this only sets the per-app preference.View on GitHub (pinned to 0bd1c6f4f9)
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
Example fix
// before if (!response?.success) throw new Error(response?.message || 'Failed to dispatch update check') // after if (!response?.success) throw new Error(response?.message || response?.error || 'Failed to dispatch update check')
Defensive patterns
Strategy: try-catch
Validate before calling
if (checkingUpdates) return
Try / catch
try {
setCheckingUpdates(true)
const r = await api.checkServiceUpdates()
if (!r?.success) throw new Error(r?.message || 'Failed to dispatch update check')
} catch (error: any) {
showError(`Failed to check for updates: ${error?.message || 'Unknown error'}`)
} finally {
setCheckingUpdates(false)
} Prevention
- Disable the check button while checkingUpdates is true
- Verify online status before dispatching
- Include server message/error fields in the thrown error
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Force reinstall failed
- Failed to fetch update status
- Failed to start update
- Failed to fetch update logs
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/c7baa903be203ef8.
Report an issue: GitHub.