{"record":{"id":"a5fddff4d7f93b0f","repo":"siyuan-note/siyuan","slug":"panic-during-siyuan-storage-put-v","errorCode":null,"errorMessage":"panic during siyuan.storage.put: %v","messagePattern":"panic during siyuan\\.storage\\.put: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":260,"sourceCode":"\t\t\tif argErr != nil {\n\t\t\t\terr = argErr\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif util.ReadOnly {\n\t\t\t\terr = fmt.Errorf(\"The current kernel is in read-only mode, storage.put 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\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.put: %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.put 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.put 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 mkdirErr := os.MkdirAll(filepath.Dir(abs), 0755); mkdirErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"failed to make directory: %w\", mkdirErr)","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L242-L278","documentation":"The goroutine performing the mkdir/write for siyuan.storage.put(path, content) recovered from a Go panic; the panic value is embedded and the Promise rejected. Normal I/O failures are reported with their own messages; this wrapper indicates an unexpected internal defect during the put pipeline.","triggerScenarios":"A panic in os.MkdirAll, filelock.WriteFile, or the result/resolution code path inside the put goroutine; nil dereferences or slice bugs in the storage layer under concurrency or unusual filesystem states.","commonSituations":"Race conditions between concurrent puts from the same plugin; kernel-internal bugs; exotic filesystem states (e.g. path component becoming a file mid-write) that trip an unchecked assumption.","solutions":["Inspect the embedded panic value in the rejection for the concrete cause","Serialize your plugin's storage.put calls (await each before the next) to rule out races","Retry the put once — transient races often succeed on the second attempt","Report reproducible panics with the message text to the SiYuan kernel maintainers"],"exampleFix":"// before\nawait Promise.all(paths.map(p => siyuan.storage.put(p, data)));\n// after\nfor (const p of paths) {\n  try { await siyuan.storage.put(p, data); }\n  catch (e) { console.error(\"put failed:\", e.message); }\n}","handlingStrategy":"try-catch","validationCode":"if (typeof path !== \"string\" || typeof content !== \"string\") throw new TypeError(\"put requires string path and content\");","typeGuard":"null","tryCatchPattern":"try { await siyuan.storage.put(path, content); } catch (e) { console.error(\"storage.put panic:\", e.message); await retryOnce(() => siyuan.storage.put(path, content)); }","preventionTips":["Await each put before starting the next; avoid parallel writes to the same path","Retry once on failure — many panic triggers are transient races","Keep unusual characters and very long paths out of storage paths","Report reproducible panics with the embedded value to SiYuan maintainers"],"tags":["plugins","panic","filesystem","siyuan"],"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"}