{"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/251596fc0de2f9528c00c224252fd073a99973f4/kernel/plugin/api_storage.go#L55-L91","documentation":"Thrown when p.addStorageWatch(abs) returns an error after the path was successfully resolved. The kernel registers the absolute storage path with its underlying file watcher (fsnotify-based); if registration fails the promise rejects with the wrapped underlying error in place of %v. Common underlying causes: the path does not exist yet, permission denied, OS watcher/inotify limits exceeded, or the path is a file whose parent cannot be watched.","triggerScenarios":"watcher.add('subdir/file.json') where 'subdir/file.json' does not exist on disk; on Linux hitting fs.inotify.max_user_watches; on Windows a path held open exclusively by another process; watching a network mount the watcher cannot monitor.","commonSituations":"Plugin tries to watch a path before creating it (call put first, then add); deployment on a restricted container with low inotify limits; symlinked storage dir on a filesystem fsnotify does not support.","solutions":["Ensure the file or directory exists (create it via storage.put) before calling watcher.add.","Raise the OS watcher limit (e.g. echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf on Linux).","Check file permissions on the storage dir and its parents.","Watch the parent directory instead of a non-existent leaf when appropriate."],"exampleFix":"// before\nawait siyuan.storage.watcher.add('cache/state.json');\n// after\nawait siyuan.storage.put('cache/state.json', '{}');\nawait siyuan.storage.watcher.add('cache/state.json');","handlingStrategy":"try-catch","validationCode":"// Ensure target exists before watching:\ntry { await siyuan.storage.get(path); } catch { await siyuan.storage.put(path, ''); }","typeGuard":null,"tryCatchPattern":"try {\n  await siyuan.storage.watcher.add(path);\n} catch (e) {\n  console.warn('watcher.add failed:', String(e));\n  // optionally retry once after ensuring the file exists\n}","preventionTips":["Create the file or directory with storage.put before watching it.","On Linux, raise fs.inotify.max_user_watches for plugins that watch many paths.","Confirm the storage dir is on a local filesystem fsnotify supports."],"tags":["plugin-api","storage","watcher","fsnotify","filesystem","environment"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}