{"record":{"id":"9b0f5322ae480126","repo":"siyuan-note/siyuan","slug":"panic-during-siyuan-storage-list-v","errorCode":null,"errorMessage":"panic during siyuan.storage.list: %v","messagePattern":"panic during siyuan\\.storage\\.list: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":409,"sourceCode":"\t\t} else {\n\t\t\tpath = call.Argument(0).String()\n\t\t}\n\n\t\trunErr := p.worker.Run(func(rt *goja.Runtime) (result any, err error) {\n\t\t\tif argErr != nil {\n\t\t\t\terr = argErr\n\t\t\t\treturn\n\t\t\t}\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\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.list: %v\", r)\n\t\t\t\t\t}\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.list 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.list 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\tentries, readErr := os.ReadDir(abs)\n\t\t\t\tif readErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to read directory: %w\", readErr)","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L391-L427","documentation":"The background goroutine that lists the directory for siyuan.storage.list has a deferred recover(); any panic during the listing or the Promise resolve/reject bridge is converted to this error and rejects the Promise. It indicates an unexpected internal crash rather than a caller-visible filesystem problem.","triggerScenarios":"A runtime panic inside the storage.list goroutine, e.g. while building the result array or while re-entering the goja worker to resolve the Promise. Rare and typically kernel-internal.","commonSituations":"Plugin/worker being torn down concurrently with an in-flight list; goja runtime bridge faults; kernel bugs.","solutions":["Check kernel logs for the panic context and report with the plugin name","Await all storage Promises before unloading/disabling the plugin","Retry the list operation once","Update the kernel and plugin to latest versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const entries = await siyuan.storage.list(dir);\n} catch (e) {\n  if (String(e).includes(\"panic during\")) {\n    console.error(\"kernel-internal panic during list; check kernel logs\");\n  } else throw e;\n}","preventionTips":["Await pending storage Promises before plugin unload","Avoid concurrent storage calls racing shutdown","Keep kernel and plugins updated"],"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"}