{"record":{"id":"eea1a31eb7a74be4","repo":"benbjohnson/litestream","slug":"parse-replica-url-w","errorCode":null,"errorMessage":"parse replica url: %w","messagePattern":"parse replica url: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":946,"sourceCode":"\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)\n\tif relPath == \"\" || relPath == \".\" {\n\t\treturn &replicaCopy, nil\n\t}\n\n\tif replicaCopy.URL != \"\" {\n\t\tu, err := url.Parse(replicaCopy.URL)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"parse replica url: %w\", err)\n\t\t}\n\t\tappendRelativePathToURL(u, relPath)\n\t\treplicaCopy.URL = u.String()\n\t\treturn &replicaCopy, nil\n\t}\n\n\tswitch base.ReplicaType() {\n\tcase \"file\":\n\t\trelOSPath := filepath.FromSlash(relPath)\n\t\tif replicaCopy.Path != \"\" {\n\t\t\treplicaCopy.Path = filepath.Join(replicaCopy.Path, relOSPath)\n\t\t} else {\n\t\t\treplicaCopy.Path = relOSPath\n\t\t}\n\tdefault:\n\t\t// Normalize to forward slashes for cloud/object storage backends.\n\t\tbasePath := filepath.ToSlash(replicaCopy.Path)\n\t\tif basePath != \"\" {","sourceCodeStart":928,"sourceCodeEnd":964,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L928-L964","documentation":"Raised when the `url` field of a replica config in the deprecated replicas array cannot be parsed by Go's net/url.Parse while rewriting it with the database's relative path. The parse error is chained, and the surrounding database fails to load.","triggerScenarios":"A replica entry whose `url` string is malformed for Go's url.Parse (e.g. invalid percent-encoding like `%zz`, control characters) encountered during config-directory loading.","commonSituations":"Hand-edited YAML with a broken URL (missing scheme is usually fine for url.Parse, but `http://[bad-ipv6` or stray `%` sequences are not); shell-interpolated env vars producing garbage in the URL.","solutions":["Fix the replica `url` value so it is a valid URL (check percent-escapes and brackets)","Check the wrapped %w error for the exact parse failure position","Validate the URL with a quick `python3 -c`/curl test or Go snippet before deploying the config"],"exampleFix":"# before\nreplicas:\n  - url: s3://%ZZ@bucket/db\n# after\nreplicas:\n  - url: s3://bucket/db","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(replica.URL); err != nil {\n    return fmt.Errorf(\"replica url %q invalid: %w\", replica.URL, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate replica URLs with net/url.Parse before writing configs","Avoid raw env interpolation into URLs; quote and escape values","Keep URLs ASCII without stray percent signs"],"tags":["config","url","parsing"],"backgroundTag":"invalid-url","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}