{"record":{"id":"9b7d5bac84432108","repo":"siyuan-note/siyuan","slug":"panic-during-siyuan-storage-remove-v","errorCode":null,"errorMessage":"panic during siyuan.storage.remove: %v","messagePattern":"panic during siyuan\\.storage\\.remove: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":341,"sourceCode":"\t\t\tif util.ReadOnly {\n\t\t\t\terr = fmt.Errorf(\"The current kernel is in read-only mode, storage.remove is not allowed\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tabs, resolveErr := resolvePath(path)\n\t\t\tif resolveErr != nil {\n\t\t\t\terr = resolveErr\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif abs == p.storageDir {\n\t\t\t\terr = fmt.Errorf(\"cannot remove storage root\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tgo func() (result any, err error) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\terr = fmt.Errorf(\"panic during siyuan.storage.remove: %v\", r)\n\t\t\t\t\t}\n\n\t\t\t\t\tp.worker.Run(func(rt *goja.Runtime) (_ any, _ error) {\n\t\t\t\t\t\tif lo.IsNil(err) {\n\t\t\t\t\t\t\tif resolveErr := resolve(result); resolveErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove resolve: %v\", p.Name, resolveErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.remove reject: %v\", p.Name, rejectErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}, nil)\n\t\t\t\t}()\n\n\t\t\t\tif removeErr := os.RemoveAll(abs); removeErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to remove: %w\", removeErr)","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L323-L359","documentation":"The background goroutine executing os.RemoveAll for siyuan.storage.remove has a deferred recover(); if the removal pipeline panics, the panic is converted into this error and the plugin's Promise is rejected with it. It signals an unexpected internal crash, not a normal filesystem error (those surface as 'failed to remove').","triggerScenarios":"A runtime panic inside the storage.remove goroutine while executing or while resolving/rejecting the Promise via the goja worker. Rare; typically indicates a bug in the runtime bridge rather than caller input.","commonSituations":"Kernel-internal panics in the JS-worker bridge; concurrently closing the plugin/worker while a removal is in flight; goja runtime state corruption.","solutions":["Check the kernel log for the surrounding stack/panic message and report it with the plugin name","Ensure the plugin is not being unloaded while storage operations are pending (await Promises before unload)","Retry the removal once; transient runtime state issues may clear","Update SiYuan kernel and the plugin to the latest versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await siyuan.storage.remove(path);\n} catch (e) {\n  if (String(e).includes(\"panic during\")) {\n    console.error(\"kernel-internal panic; report with kernel logs\");\n  } else throw e;\n}","preventionTips":["Await all storage Promises before unloading the plugin","Keep kernel and plugins up to date","Report persistent panics with kernel logs and plugin name"],"tags":["plugin","storage","panic","goja"],"backgroundTag":"internal-invariant-violation","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"}