{"record":{"id":"d6796f675efa2e10","repo":"benbjohnson/litestream","slug":"database-config-d-watch-can-only-be-enabled-w","errorCode":null,"errorMessage":"database config #%d: 'watch' can only be enabled with a directory","messagePattern":"database config #(.+?): 'watch' can only be enabled with a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":518,"sourceCode":"\t\t}\n\n\t\t// Reject the same database path listed twice. The metadata directory is\n\t\t// derived from the path, so two entries would share it and race on the\n\t\t// same LTX temp files.\n\t\tif db.Path != \"\" {\n\t\t\tkey := filepath.Clean(db.Path)\n\t\t\tif first, ok := seenPaths[key]; ok {\n\t\t\t\treturn fmt.Errorf(\"database config #%d: duplicate path %q (already used by database config #%d); each database can be listed only once\", idx+1, db.Path, first)\n\t\t\t}\n\t\t\tseenPaths[key] = idx + 1\n\t\t}\n\n\t\t// When using dir, pattern must be specified\n\t\tif db.Dir != \"\" && db.Pattern == \"\" {\n\t\t\treturn fmt.Errorf(\"database config #%d: 'pattern' is required when using 'dir'\", idx+1)\n\t\t}\n\t\tif db.Watch && db.Dir == \"\" {\n\t\t\treturn fmt.Errorf(\"database config #%d: 'watch' can only be enabled with a directory\", idx+1)\n\t\t}\n\t\tif db.MetaDir != nil && db.Dir == \"\" {\n\t\t\treturn fmt.Errorf(\"database config #%d: 'meta-dir' can only be used with a directory\", idx+1)\n\t\t}\n\t\tif db.MetaPath != nil && db.MetaDir != nil {\n\t\t\treturn fmt.Errorf(\"database config #%d: cannot specify both 'meta-path' and 'meta-dir'\", idx+1)\n\t\t}\n\n\t\t// Use path or dir for identifying the config in error messages\n\t\tdbIdentifier := db.Path\n\t\tif dbIdentifier == \"\" {\n\t\t\tdbIdentifier = db.Dir\n\t\t}\n\n\t\tif db.Snapshot.Interval != nil && *db.Snapshot.Interval <= 0 {\n\t\t\treturn &ConfigValidationError{\n\t\t\t\tErr:   ErrInvalidSnapshotInterval,\n\t\t\t\tField: fmt.Sprintf(\"dbs[%s].snapshot.interval\", dbIdentifier),","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L500-L536","documentation":"Validate() in cmd/litestream/main.go rejects a database config entry where 'watch: true' is set but no 'dir' is configured. Watch-mode file monitoring only works for directory-based replication, where Litestream scans a directory for SQLite databases; for a single-database 'path' config it is meaningless. The check fires per database entry during config parsing.","triggerScenarios":"Running `litestream` (or ParseConfig -> Validate) with a YAML/JSON config where a databases[] entry has `watch: true` but only `path:` set (no `dir:`).","commonSituations":"User copies watch settings from a directory-replication example into a single-DB config; user misunderstands 'watch' as a general polling option and enables it on a path-based database entry.","solutions":["Remove `watch: true` from the single-database config entry, or","Convert the entry to directory-based replication by setting `dir:` (and the required `pattern:`) instead of `path:`, keeping `watch: true`.","If periodic monitoring is desired for a single DB, rely on the default monitor interval; watch is not supported for path-based configs."],"exampleFix":"# before\ndatabases:\n  - path: /var/db/app.db\n    watch: true\n# after (option A: drop watch)\ndatabases:\n  - path: /var/db/app.db\n# after (option B: use dir)\ndatabases:\n  - dir: /var/db\n    pattern: \"*.db\"\n    watch: true","handlingStrategy":"validation","validationCode":"for i, db := range cfg.Databases {\n    if db.Watch && db.Dir == \"\" {\n        return fmt.Errorf(\"db #%d: 'watch' requires 'dir'\", i+1)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only set watch:true on directory-based entries","Lint configs against the DBConfig schema before deploy","Test configs with `litestream -config file.yml` in CI"],"tags":["config","validation","litestream"],"backgroundTag":"invalid-config-value","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}