{"record":{"id":"ac9da4f160fb10bb","repo":"tinyhumansai/openhuman","slug":"app-update-hook-unknown-status-payload","errorCode":null,"errorMessage":"[app-update] hook: unknown status payload","messagePattern":"\\[app-update\\] hook: unknown status payload","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/hooks/useAppUpdate.ts","lineNumber":125,"sourceCode":"/** A short grace before the auto-download fires, so the UI can show the\n *  fact that an update was *detected* (briefly) before going into \"downloading\"\n *  state. Cosmetic, not load-bearing. */\nconst AUTO_DOWNLOAD_GRACE_MS = 1_000;\n\n/**\n * Translate a raw `app-update:status` payload into our phase enum, defaulting\n * to `error` for any unrecognized string so we don't silently swallow a bad\n * payload from the Rust side.\n */\nfunction parseStatusPayload(raw: unknown): AppUpdatePhase {\n  if (raw === 'checking') return 'checking';\n  if (raw === 'downloading') return 'downloading';\n  if (raw === 'ready_to_install') return 'ready_to_install';\n  if (raw === 'installing') return 'installing';\n  if (raw === 'restarting') return 'restarting';\n  if (raw === 'up_to_date') return 'up_to_date';\n  if (raw === 'error') return 'error';\n  console.warn('[app-update] hook: unknown status payload', raw);\n  return 'error';\n}\n\nexport function useAppUpdate(options: UseAppUpdateOptions = {}): UseAppUpdateResult {\n  const {\n    autoCheck = true,\n    initialCheckDelayMs = DEFAULT_INITIAL_DELAY_MS,\n    recheckIntervalMs = DEFAULT_RECHECK_INTERVAL_MS,\n    autoDownload = true,\n  } = options;\n\n  const [phase, setPhase] = useState<AppUpdatePhase>('idle');\n  const [info, setInfo] = useState<AppUpdateInfo | null>(null);\n  const [bytesDownloaded, setBytesDownloaded] = useState(0);\n  const [totalBytes, setTotalBytes] = useState<number | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  // Refs to keep callbacks stable + survive React 18 strict-mode double-invoke.","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/hooks/useAppUpdate.ts#L107-L143","documentation":"Defensive default in parseStatusPayload(): an `app-update:status` event arrived from the Rust side carrying a phase string not in the known set (checking/downloading/...). Rather than silently ignoring an unrecognized payload, the mapper coerces it to the 'error' phase so the UI surfaces the mismatch; the log names the offending raw value.","triggerScenarios":"Thrown at app/src/hooks/useAppUpdate.ts:125 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Compare the raw payload in the log with the Rust-side status enum to find the added/renamed variant","Extend the TS union and parser when the Rust side legitimately adds a status","Treat unknown payloads as no-op instead of error if stale-version skew is expected"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}