{"record":{"id":"d4fed5ebe134f797","repo":"benbjohnson/litestream","slug":"failed-to-configure-replica-d-for-s-w","errorCode":null,"errorMessage":"failed to configure replica %d for %s: %w","messagePattern":"failed to configure replica (.+?) for (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":920,"sourceCode":"\t}\n\n\t// Deep copy replica config and make path unique per database.\n\t// This prevents all databases from writing to the same replica path.\n\tif dbc.Replica != nil {\n\t\treplicaCopy, err := cloneReplicaConfigWithRelativePath(dbc.Replica, relPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to configure replica for %s: %w\", dbPath, err)\n\t\t}\n\t\tdbConfigCopy.Replica = replicaCopy\n\t}\n\n\t// Also handle deprecated 'replicas' array field.\n\tif len(dbc.Replicas) > 0 {\n\t\tdbConfigCopy.Replicas = make([]*ReplicaConfig, len(dbc.Replicas))\n\t\tfor i, replica := range dbc.Replicas {\n\t\t\treplicaCopy, err := cloneReplicaConfigWithRelativePath(replica, relPath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to configure replica %d for %s: %w\", i, dbPath, err)\n\t\t\t}\n\t\t\tdbConfigCopy.Replicas[i] = replicaCopy\n\t\t}\n\t}\n\n\treturn NewDBFromConfig(&dbConfigCopy)\n}\n\n// cloneReplicaConfigWithRelativePath returns a copy of the replica configuration with the\n// database-relative path appended to either the replica path or URL, depending on how the\n// replica was configured.\nfunc cloneReplicaConfigWithRelativePath(base *ReplicaConfig, relPath string) (*ReplicaConfig, error) {\n\tif base == nil {\n\t\treturn nil, nil\n\t}\n\n\treplicaCopy := *base\n\trelPath = filepath.ToSlash(relPath)","sourceCodeStart":902,"sourceCodeEnd":938,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L902-L938","documentation":"This error wraps a failure that occurred while deep-copying and rewriting one entry of the deprecated 'replicas' array in a database config directory entry. Litestream resolves replica URLs against the database's relative path; if a replica config cannot be cloned (typically because its path is a URL or malformed), startup of that database is aborted and the underlying cause is chained via %w.","triggerScenarios":"Running `litestream replicate -config <dir>` where a YAML/JSON file in the config directory uses the deprecated `replicas:` array and one replica entry fails cloneReplicaConfigWithRelativePath — most often a replica whose `path` field contains a full URL that cannot be parsed or is rejected.","commonSituations":"Migrating old v0.3.x configs that used a replicas array with inline path-style S3 locations; a typo'd replica path value that url.Parse or path handling rejects.","solutions":["Move the replica out of the deprecated `replicas` array into a top-level replica config with an explicit `url` field","Fix the offending replica path so it is a relative path, not a URL (read the wrapped %w cause for the exact parse failure)","Use `litestream replicate -config <file>` with a single validated config file to isolate which replica entry fails"],"exampleFix":"# before (deprecated)\ndbs:\n  - path: /data/db.sqlite\n    replicas:\n      - path: file:///backups/db\n# after\ndbs:\n  - path: /data/db.sqlite\n    replicas:\n      - url: file:///backups/db","handlingStrategy":"validation","validationCode":"for i, r := range dbc.Replicas {\n    if r.Path != \"\" && strings.Contains(r.Path, \"://\") {\n        return fmt.Errorf(\"replicas[%d]: path %q looks like a URL; use 'url' field\", i, r.Path)\n    }\n    if r.URL != \"\" {\n        if _, err := url.Parse(r.URL); err != nil {\n            return fmt.Errorf(\"replicas[%d]: invalid url: %w\", i, err)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer top-level `url` fields over the deprecated replicas array","Lint replica paths for '://' before deploying configs","Test config-directory loading in CI with `litestream replicate -config <dir> -exec true`-style dry runs"],"tags":["config","replica","startup","deprecated"],"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"}