{"record":{"id":"fa8dbb02e6e5b0d1","repo":"benbjohnson/litestream","slug":"database-config-d-duplicate-path-q-already-us","errorCode":null,"errorMessage":"database config #%d: duplicate path %q (already used by database config #%d); each database can be listed only once","messagePattern":"database config #(.+?): duplicate path %q \\(already used by database config #(.+?)\\); each database can be listed only once","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":508,"sourceCode":"\n\t// Validate database configs\n\tseenPaths := make(map[string]int) // cleaned path -> 1-based config index\n\tfor idx, db := range c.DBs {\n\t\t// Validate that either path or dir is specified, but not both\n\t\tif db.Path != \"\" && db.Dir != \"\" {\n\t\t\treturn fmt.Errorf(\"database config #%d: cannot specify both 'path' and 'dir'\", idx+1)\n\t\t}\n\t\tif db.Path == \"\" && db.Dir == \"\" {\n\t\t\treturn fmt.Errorf(\"database config #%d: must specify either 'path' or 'dir'\", idx+1)\n\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","sourceCodeStart":490,"sourceCodeEnd":526,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L490-L526","documentation":"During config validation, litestream rejects a config file that lists the same database path in two `database` entries. The metadata directory is derived from the database path, so duplicates would share one metadata dir and race on the same LTX temp files. The message names both offending config indexes (1-based) and the duplicated path.","triggerScenarios":"ParseConfig followed by Validate on a YAML config containing two `dbs:` entries with identical `path:` values (after filepath.Clean normalization), e.g. `/var/lib/app.db` listed twice, or the same path written with redundant segments like `/var/lib/./app.db`.","commonSituations":"Merging config snippets from two files or teammates and accidentally duplicating a db entry; copy-pasting an entry to add a second replica but forgetting each database can have only one replica listed once; path aliases (symlink vs real path written differently but cleaning to the same key).","solutions":["Remove the duplicate database entry identified by the two config indexes in the message, keeping the one with the correct replica settings.","If you intended different settings for the same DB, litestream supports a single replica per database — merge the settings into one entry.","Normalize paths (no `.`/`..` segments) so matching entries are obvious; note the check compares filepath.Clean'd paths.","Run `litestream -config <file> ...` again after editing to confirm validation passes."],"exampleFix":"# before (litestream.yml)\ndbs:\n  - path: /var/lib/app.db\n    replicas:\n      - url: s3://bucket/app\n  - path: /var/lib/app.db\n    replicas:\n      - url: s3://bucket/app2\n# after\ndbs:\n  - path: /var/lib/app.db\n    replicas:\n      - url: s3://bucket/app","handlingStrategy":"validation","validationCode":"# lint config before deploy: no duplicate db paths\npaths=$(yq '.dbs[].path' litestream.yml | xargs -n1 realpath -e | sort)\nif [ \"$(echo \"$paths\" | sort -u | wc -l)\" != \"$(echo \"$paths\" | wc -l)\" ]; then\n  echo 'duplicate database path in config'; exit 1\nfi","typeGuard":null,"tryCatchPattern":"if err := cmd.Run(); err != nil {\n    var cfgErr *ConfigError // or match on 'duplicate path'\n    if strings.Contains(err.Error(), \"duplicate path\") {\n        log.Fatal(\"fix litestream.yml: remove the duplicated database entry named in the error\")\n    }\n    log.Fatal(err)\n}","preventionTips":["Keep one entry per database; a database supports exactly one replica listed once.","When merging config fragments, diff paths before concatenating dbs lists.","Write canonical absolute paths (no ./.. segments) so duplicates are visible.","Validate configs in CI before deployment."],"tags":["config","validation","duplicate"],"backgroundTag":"schema-validation-failed","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"}