{"record":{"id":"c587e623c0946f39","repo":"yikart/AiToEarn","slug":"errors-restartfailed","errorCode":null,"errorMessage":"errors.restartFailed","messagePattern":"errors\\.restartFailed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"project/aitoearn-web/src/app/layout/ConfigManagerDialog/index.tsx","lineNumber":561,"sourceCode":"        toast.success(t('messages.restartSuccess'))\n        return true\n      }\n    }\n\n    setServiceStatus('failed')\n    setError({ title: t('errors.healthTimeout'), description: t('errors.healthTimeoutDescription') })\n    return false\n  }, [serviceTarget, t])\n\n  const restartService = useCallback(async (action: LoadingAction = 'restart') => {\n    setLoadingAction(action)\n    setError(null)\n    setSuccessMessage('')\n\n    try {\n      const response = await restartConfigEditorServiceApi(serviceTarget, true)\n      if (!response || response.code !== 0) {\n        throw new Error(getResponseMessage(response) || t('errors.restartFailed'))\n      }\n\n      await waitForHealth()\n    }\n    catch (restartError) {\n      setServiceStatus('failed')\n      setError({ title: t('errors.restartFailed'), description: getErrorMessage(restartError) })\n    }\n    finally {\n      setLoadingAction(null)\n    }\n  }, [serviceTarget, t, waitForHealth])\n\n  const handleSaveAndRestart = useCallback(async () => {\n    const saved = await saveConfig('saveRestart')\n    if (!saved) {\n      setLoadingAction(null)\n      return","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-web/src/app/layout/ConfigManagerDialog/index.tsx#L543-L579","documentation":"ConfigManagerDialog's restart handler throws this fallback Error when restartConfigEditorServiceApi returns a non-zero code or an empty response without a backend message. The catch block sets serviceStatus to 'failed', signaling the service could not be restarted from the dialog.","triggerScenarios":"Calling restartConfigEditorServiceApi(serviceTarget, true) and receiving null/undefined response or response.code !== 0 with no message; also when the subsequent waitForHealth() throws.","commonSituations":"Relay/config-editor process cannot be restarted (port in use, crashed supervisor); health check never turns green after restart; service binary missing on host; insufficient permissions to restart.","solutions":["Check the target service host: process status, port conflicts, and supervisor/logs","Verify health endpoint becomes responsive after restart (increase waitForHealth timeout if slow)","Confirm the API caller has permission to trigger restarts for serviceTarget","Retry restart; if it repeatedly fails, restart the service manually on the host"],"exampleFix":"// before\nif (!response || response.code !== 0) {\n  throw new Error(getResponseMessage(response) || t('errors.restartFailed'))\n}\n// after\nif (!response || response.code !== 0) {\n  setServiceStatus('failed')\n  setError(getResponseMessage(response) || t('errors.restartFailed'))\n  return\n}","handlingStrategy":"try-catch","validationCode":"const health = await fetch(healthUrl); if (!health.ok) throw new Error('service unhealthy before restart')","typeGuard":null,"tryCatchPattern":"try {\n  const response = await restartConfigEditorServiceApi(serviceTarget, true)\n  if (!response || response.code !== 0)\n    throw new Error(getResponseMessage(response) || 'restart failed')\n  await waitForHealth()\n} catch (e) {\n  setServiceStatus('failed')\n  setError(e instanceof Error ? e.message : 'restart failed')\n}","preventionTips":["Set a generous waitForHealth timeout with polling rather than a single check","Distinguish restart-call failure from health-check timeout in messages","Check service process/port state on the host on repeated failures","Disable the restart button while a restart is in flight"],"tags":["service-restart","health-check","config"],"backgroundTag":"service-restart-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}