{"record":{"id":"3ad1edd0131fe6dd","repo":"siyuan-note/siyuan","slug":"failed-to-terminate-residual-kernel-processes-por","errorCode":null,"errorMessage":"failed to terminate residual kernel processes [ports=\" + residualPorts.join(\",\") + \"]","messagePattern":"failed to terminate residual kernel processes \\[ports=\" \\+ residualPorts\\.join\\(\",\"\\) \\+ \"\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/electron/main.js","lineNumber":1703,"sourceCode":"    if (timedOutPorts.length === 0) {\n        return;\n    }\n\n    writeLog(\"kernel exit timed out before update [ports=\" + timedOutPorts.join(\",\") + \"]\");\n    timedOutPorts.forEach((port) => {\n        const kernelProcess = kernelProcesses.get(port);\n        if (kernelProcess) {\n            writeLog(\"terminating residual kernel before update [pid=\" + kernelProcess.pid + \", port=\" + port + \"]\");\n            kernelProcess.kill(\"SIGKILL\");\n        }\n    });\n    await Promise.all(timedOutPorts.map((port) => waitForKernelProcessExit(port, 5000)));\n    const residualPorts = timedOutPorts.filter((port) => kernelProcesses.has(port));\n    if (residualPorts.length > 0) {\n        if (process.platform === \"win32\") {\n            writeLog(\"residual kernel processes will be terminated by the installer [ports=\" + residualPorts.join(\",\") + \"]\");\n        } else {\n            throw new Error(\"failed to terminate residual kernel processes [ports=\" + residualPorts.join(\",\") + \"]\");\n        }\n    }\n};\n\nconst closeUpdateKernelStage = async (ports, request) => {\n    if (ports.length === 0) {\n        return [];\n    }\n\n    const exitResponses = await Promise.all(ports.map((port) => closeKernelForUpdate(port, request.initiatingPort,\n        request.setCurrentWorkspace)));\n    ports.forEach((port) => exitApp(port));\n    await waitForUpdateKernelExits(ports);\n    return exitResponses;\n};\n\n// 更新时先退出其他工作空间，再退出发起更新的工作空间，确保安装器启动前所有内核已经停止。\n// https://github.com/siyuan-note/siyuan/issues/18258","sourceCodeStart":1685,"sourceCodeEnd":1721,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/app/electron/main.js#L1685-L1721","documentation":"During the update flow, after waiting for kernel processes on timed-out ports to exit, some ports still have live kernel processes. On Windows the installer handles killing them, but on non-Windows platforms Electron has no reliable way to kill them, so it aborts the update with this error naming the affected ports.","triggerScenarios":"An in-app update is initiated while kernel processes from this or other workspaces ignore SIGTERM/SIGKILL within the 5-second waitForKernelProcessExit window on Linux/macOS; residualPorts is non-empty and process.platform !== \"win32\".","commonSituations":"A frozen or wedged kernel process holding the workspace port; multiple open workspaces whose kernels have not shut down in time; a kernel stuck in startup/shutdown due to I/O or a deadlock; running the app under a process supervisor that respawns kernels.","solutions":["Manually inspect and kill the lingering kernel process for the listed ports (lsof -i :PORT / ps aux | grep siyuan-kernel), then retry the update","Close all other SiYuan workspaces before updating so fewer kernels need to exit","Reboot if the process is unkillable (e.g. stuck in uninterruptible I/O sleep)","On Windows, no action is needed: the installer is expected to terminate residual processes"],"exampleFix":"// Hard to fix in caller code; operator-level remediation:\n// before\n//   update fails: failed to terminate residual kernel processes [ports=6806]\n// after\n//   $ lsof -i :6806          # find PID holding the port\n//   $ kill -9 <pid>\n//   # retry the in-app update","handlingStrategy":"validation","validationCode":"if !notebookCryptoConfigurationComplete(&Conf.NotebookCrypto) {\n    // repair via backup import or re-run EnableEncryptedNotebook before saving\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not hand-edit the NotebookCrypto section of conf.json","Always enable encryption through EnableEncryptedNotebook rather than editing config directly"],"tags":["process-lifecycle","update","electron","kernel-shutdown"],"backgroundTag":"process-termination-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}