{"record":{"id":"f3c6ff963b94e0bf","repo":"benbjohnson/litestream","slug":"database-config-d-meta-dir-can-only-be-used-w","errorCode":null,"errorMessage":"database config #%d: 'meta-dir' can only be used with a directory","messagePattern":"database config #(.+?): 'meta-dir' can only be used with a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":521,"sourceCode":"\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),\n\t\t\t\tValue: *db.Snapshot.Interval,\n\t\t\t}\n\t\t}","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L503-L539","documentation":"Validate() rejects a database config entry that sets 'meta-dir' without a 'dir'. The meta-dir option (where Litestream stores metadata for directory-managed databases) only applies to directory replication, so it is invalid on a single-path database entry.","triggerScenarios":"Running `litestream` with a databases[] entry containing `meta-dir:` while `dir:` is absent (only `path:` or nothing). Caught by Validate during ParseConfig.","commonSituations":"User adds meta-dir to a single-database config intending to relocate metadata; user confuses meta-dir with meta-path, which is the valid option for single-DB configs.","solutions":["For a single-database entry, replace `meta-dir:` with `meta-path:` to set a custom metadata location.","Or switch the entry to directory replication by adding `dir:` (plus `pattern:`), which permits meta-dir.","Or remove meta-dir entirely if default metadata placement is fine."],"exampleFix":"# before\ndatabases:\n  - path: /var/db/app.db\n    meta-dir: /var/lib/litestream-meta\n# after\ndatabases:\n  - path: /var/db/app.db\n    meta-path: /var/lib/litestream-meta/app","handlingStrategy":"validation","validationCode":"if db.MetaDir != nil && db.Dir == \"\" {\n    return fmt.Errorf(\"db #%d: 'meta-dir' requires 'dir'\", i+1)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use meta-path for single-DB entries, meta-dir only under dir replication","Validate configs in CI before rollout","Document which keys apply to dir vs path entries"],"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"}