{"record":{"id":"208618bf77253d0a","repo":"benbjohnson/litestream","slug":"create-per-connection-replica-client-w","errorCode":null,"errorMessage":"create per-connection replica client: %w","messagePattern":"create per-connection replica client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"vfs.go","lineNumber":160,"sourceCode":"\tcase vfs.requiresTempFile(flags):\n\t\treturn vfs.openTempFile(name, flags)\n\tdefault:\n\t\treturn nil, flags, sqlite3vfs.CantOpenError\n\t}\n}\n\nfunc (vfs *VFS) openMainDB(name string, uriParameters map[string]string, flags sqlite3vfs.OpenFlag) (sqlite3vfs.File, sqlite3vfs.OpenFlag, error) {\n\tcfg, err := vfs.configForOpen(name, uriParameters)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\tclient := vfs.client\n\tvar perConnClient bool\n\tif cfg != nil && cfg.ReplicaURL != \"\" {\n\t\tclient, err = NewReplicaClientFromURL(cfg.ReplicaURL)\n\t\tif err != nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"create per-connection replica client: %w\", err)\n\t\t}\n\t\tif err := client.Init(context.Background()); err != nil {\n\t\t\tif closer, ok := client.(io.Closer); ok {\n\t\t\t\tif closeErr := closer.Close(); closeErr != nil {\n\t\t\t\t\treturn nil, 0, fmt.Errorf(\"init per-connection replica client: %w\", errors.Join(err, closeErr))\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil, 0, fmt.Errorf(\"init per-connection replica client: %w\", err)\n\t\t}\n\t\tperConnClient = true\n\t}\n\n\tif client == nil {\n\t\treturn nil, 0, fmt.Errorf(\"no replica client configured: set LITESTREAM_REPLICA_URL, use SetVFSConfig, or pass replica_url in the database URI\")\n\t}\n\n\tf := NewVFSFile(client, name, vfs.logger.With(\"name\", name))\n\tf.PollInterval = vfs.PollInterval","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L142-L178","documentation":"In openMainDB, when a VFS connection specifies cfg.ReplicaURL (via URI parameter 'replica_url' or per-connection config), a dedicated replica client is created from that URL with NewReplicaClientFromURL. This error wraps the failure of that URL-to-client construction. Litestream throws it because the read-only VFS cannot open the database without a working replica client backend.","triggerScenarios":"Opening a database with a URI like 'file:/path/db?vfs=litestream&replica_url=s3://bucket/db' where the replica_url scheme is unregistered/unknown (e.g. typo 's33://'), or the URL is malformed so the scheme/endpoint cannot be extracted.","commonSituations":"Typos in the replica URL scheme; using a backend whose driver package was not imported/registered (e.g. missing Azure/GCS client registration); copy-pasting URLs with extra characters or wrong quoting in connection strings.","solutions":["Check the replica_url scheme is one of the registered backends (s3, gs, azure, file, sftp) and spelled correctly.","Ensure the storage backend package is imported (directly or via the litestream all-packages import) so its replica client is registered.","URL-encode the replica_url properly inside the database URI; test the same URL with 'litestream replicate' to validate it.","Fall back to the global configuration: set LITESTREAM_REPLICA_URL or call SetVFSConfig instead of the per-connection URL."],"exampleFix":"// before\nsql.Open(\"sqlite\", \"file:app.db?vfs=litestream&replica_url=s33://bucket/db\")\n\n// after\nsql.Open(\"sqlite\", \"file:app.db?vfs=litestream&replica_url=s3://my-bucket/app.db\")","handlingStrategy":"validation","validationCode":"u, err := url.Parse(replicaURL)\nif err != nil || u.Scheme == \"\" {\n    return fmt.Errorf(\"invalid replica_url %q\", replicaURL)\n}\nswitch u.Scheme {\ncase \"s3\", \"gs\", \"azure\", \"file\", \"sftp\":\n    // ok\ndefault:\n    return fmt.Errorf(\"unregistered replica scheme %q\", u.Scheme)\n}","typeGuard":null,"tryCatchPattern":"db, err := sql.Open(\"sqlite\", dsn)\nif err != nil {\n    var probeErr error\n    _, probeErr = litestream.NewReplicaClientFromURL(replicaURL)\n    return fmt.Errorf(\"open failed; replica client error: %w\", errors.Join(err, probeErr))\n}","preventionTips":["Test the replica URL with the litestream CLI before wiring it into connection strings","Import the storage backend packages so schemes are registered at init","URL-encode replica_url when embedding it in a SQLite URI","Keep a config-level allowlist of supported schemes and validate at startup"],"tags":["replica-client","url-parsing","vfs","configuration"],"backgroundTag":"invalid-url","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"}