{"record":{"id":"73e1ae11e367436c","repo":"siyuan-note/siyuan","slug":"failed-to-add-storage-path-to-watcher-v","errorCode":null,"errorMessage":"failed to add storage path to watcher: %v","messagePattern":"failed to add storage path to watcher: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/api_storage.go","lineNumber":73,"sourceCode":"\t\tvar path string\n\t\tif len(call.Arguments) >= 1 && goja.IsString(call.Argument(0)) {\n\t\t\tpath = call.Argument(0).String()\n\t\t} else {\n\t\t\targErr = fmt.Errorf(\"path required\")\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\t\t\tif addErr := p.addStorageWatch(abs); addErr != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to add storage path to watcher: %v\", addErr)\n\t\t\t}\n\t\t\treturn\n\t\t}, func(rt *goja.Runtime, result any, err error) {\n\t\t\tif lo.IsNil(err) {\n\t\t\t\tif resolveErr := resolve(result); resolveErr != nil {\n\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.watcher.add resolve: %v\", p.Name, resolveErr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif rejectErr := reject(rt.NewGoError(err)); rejectErr != nil {\n\t\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.watcher.add reject: %v\", p.Name, rejectErr)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tif runErr != nil {\n\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.watcher.add worker run: %v\", p.Name, runErr)\n\t\t\tif rejectErr := reject(rt.NewGoError(runErr)); rejectErr != nil {\n\t\t\t\tlogging.LogErrorf(\"[plugin:%s] siyuan.storage.watcher.add reject: %v\", p.Name, rejectErr)\n\t\t\t}","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/api_storage.go#L55-L91","documentation":"siyuan.storage.watcher.add registers a path with the kernel's filesystem watcher via p.addStorageWatch. When the underlying watcher refuses the path (already watched, does not exist, OS limit reached), the promise rejects with 'failed to add storage path to watcher: %v' wrapping the cause.","triggerScenarios":"Calling storage.watcher.add('relpath') where the resolved absolute path cannot be added: directory missing, path already being watched, inotify/FSEvents watch limit exhausted, or permission problems.","commonSituations":"Watching a file that was deleted or not yet created; adding the same path twice across plugin reloads; long-running kernels hitting the OS inotify watch limit; restricted filesystems that disallow watches.","solutions":["Read the wrapped cause to distinguish not-exists vs already-watched vs limit-exceeded","Ensure the path exists inside plugin storage before calling watcher.add","Deduplicate: track which paths are already watched and skip re-adding","Raise the OS watch limit (e.g. fs.inotify.max_user_watches on Linux) if exhausted","Create the target directory first (storage.set a placeholder or mkdir) then add the watch"],"exampleFix":"// before\nawait siyuan.storage.watcher.add('logs/') // dir may not exist\n// after\nawait siyuan.storage.set('logs/.keep', '')\nif (!watched.has('logs/')) {\n  watched.add('logs/')\n  await siyuan.storage.watcher.add('logs/')\n}","handlingStrategy":"try-catch","validationCode":"if (typeof path !== 'string' || !path) throw new TypeError('watcher path required')","typeGuard":null,"tryCatchPattern":"try { await siyuan.storage.watcher.add(rel) } catch (e) { if (String(e.message).includes('failed to add storage path to watcher')) { /* ensure path exists / skip duplicates / raise OS watch limit */ } else throw e }","preventionTips":["Ensure the target path exists before watching","Track already-watched paths to avoid duplicate registration","Monitor OS watch limits on long-running instances","Re-register watches after plugin reload from a persisted list with deduplication"],"tags":["filesystem","watcher","storage"],"backgroundTag":"file-watch-failed","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"}