{"record":{"id":"e64fa54607c2cf1e","repo":"siyuan-note/siyuan","slug":"kernel-is-exiting","errorCode":null,"errorMessage":"kernel is exiting","messagePattern":"kernel is exiting","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/hpath_refresh.go","lineNumber":260,"sourceCode":"\tif err = saveHPathRefreshLocked(); err != nil {\n\t\tif previous == nil {\n\t\t\tdelete(hpathRefresh.tasks, key)\n\t\t} else {\n\t\t\thpathRefresh.tasks[key] = previous\n\t\t}\n\t}\n\treturn\n}\n\nfunc writeRenameDoc(tree *parse.Tree) (size uint64, err error) {\n\tif err = AcquireEncryptedBoxOperation(tree.Box); err != nil {\n\t\treturn\n\t}\n\tdefer ReleaseEncryptedBoxOperation(tree.Box)\n\thpathRefresh.Lock()\n\tdefer hpathRefresh.Unlock()\n\tif util.IsExiting.Load() {\n\t\treturn 0, errors.New(\"kernel is exiting\")\n\t}\n\ttree.HPath = treenode.CurrentParentHPath(tree)\n\tkey, err := queueHPathRefreshLocked(tree)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif size, err = filesys.WriteTree(tree); err != nil {\n\t\treturn\n\t}\n\tif treenode.GetBlockTreeInBox(tree.ID, tree.Box) == nil {\n\t\ttreenode.UpsertBlockTree(tree)\n\t}\n\tif err = treenode.RefreshDocHPaths(tree); err != nil {\n\t\treturn\n\t}\n\tsql.RenameDocQueue(tree)\n\thpathRefresh.tasks[key].recover = false\n\treturn","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/hpath_refresh.go#L242-L278","documentation":"writeRenameDoc performs the document rename write while holding the hpath refresh lock. Before writing it checks util.IsExiting; if the kernel is shutting down it aborts with this error so a rename is never half-applied during shutdown, which could leave document paths and the hpath refresh queue inconsistent.","triggerScenarios":"Invoking a document rename API (which reaches renameWriteJSONQueue -> writeRenameDoc) while the kernel is shutting down (util.IsExiting set), e.g. a rename request racing the quit sequence.","commonSituations":"Scripts or automation issuing rename calls right as the user closes the app; long-running API requests delayed until after shutdown started; CI/scripts that kill the kernel while requests are in flight.","solutions":["Retry the rename after the kernel restarts","Ensure the kernel is fully stopped before issuing further API calls in shutdown/automation scripts","Add a shutdown hook or ordering so renames are drained before the exit flag is set","Handle the returned error in the caller and surface 'kernel is shutting down' to the user instead of a generic failure"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"n, err := model.RenameDoc(box, path, title); if err != nil && err.Error() == \"kernel is exiting\" { // wait for restart, then retry the rename }","preventionTips":["Do not fire rename API calls during kernel shutdown","In automation, wait for a health check before issuing mutations","Drain pending mutations before setting the exit flag in custom tooling"],"tags":["shutdown","concurrency","rename","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}