{"record":{"id":"39557a3c8a3e67c0","repo":"benbjohnson/litestream","slug":"no-replica-client-configured","errorCode":null,"errorMessage":"no replica client configured","messagePattern":"no replica client configured","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":738,"sourceCode":"\n\tif err := db.Sync(ctx); err != nil {\n\t\treturn fmt.Errorf(\"db sync: %w\", err)\n\t}\n\tif err := db.Replica.Sync(ctx); err != nil {\n\t\treturn fmt.Errorf(\"replica sync: %w\", err)\n\t}\n\treturn nil\n}\n\n// EnsureExists restores the database from the configured replica if the local\n// database file does not exist. If no backup is available, it returns nil and\n// a fresh database will be created on Open(). Must be called before Open().\nfunc (db *DB) EnsureExists(ctx context.Context) error {\n\tif db.Replica == nil {\n\t\treturn fmt.Errorf(\"no replica configured\")\n\t}\n\tif db.Replica.Client == nil {\n\t\treturn fmt.Errorf(\"no replica client configured\")\n\t}\n\n\tif _, err := os.Stat(db.Path()); err == nil {\n\t\treturn nil\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"stat database: %w\", err)\n\t}\n\n\tif dir := filepath.Dir(db.Path()); dir != \".\" {\n\t\tif err := os.MkdirAll(dir, 0o750); err != nil {\n\t\t\treturn fmt.Errorf(\"create parent directory: %w\", err)\n\t\t}\n\t}\n\n\topt := NewRestoreOptions()\n\topt.OutputPath = db.Path()\n\topt.IntegrityCheck = IntegrityCheckQuick\n","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L720-L756","documentation":"DB.EnsureExists(ctx) requires both a Replica and a Replica.Client. This error means db.Replica exists but its storage client was never initialized, so litestream cannot talk to the replica destination to restore the database.","triggerScenarios":"Calling db.EnsureExists(ctx) on a DB whose Replica was constructed manually (e.g. litestream.NewReplica without calling replica.Client assignment / init) or whose client failed to initialize from config.","commonSituations":"Library users building Replica structs directly instead of via config loading, forgetting to set Client (e.g. s3.NewReplicaClient()); a custom replica_client.go backend not wired into the client factory; config loaded with an unsupported replica type yielding a nil client.","solutions":["Initialize the client: assign the appropriate ReplicaClient (e.g. &s3.ReplicaClient{...} or via config load) to db.Replica.Client.","Prefer loading replicas from config (which wires the client) rather than hand-constructing them.","If you implement a custom backend, follow docs/REPLICA_CLIENT_GUIDE.md and register it so the client is created from config.","Guard: check db.Replica.Client != nil before EnsureExists and return a clear config error."],"exampleFix":"// before\ndb.Replica = litestream.NewReplica(db, replicaConfig)\ndb.EnsureExists(ctx) // error: no replica client configured\n// after\ndb.Replica = litestream.NewReplica(db, replicaConfig)\ndb.Replica.Client = s3.NewReplicaClient() // configure bucket/region/creds\nif err := db.Replica.Client.Init(ctx); err != nil { return err }\ndb.EnsureExists(ctx)","handlingStrategy":"validation","validationCode":"if db.Replica == nil || db.Replica.Client == nil {\n    return errors.New(\"replica client not initialized; build replica via config\")\n}","typeGuard":null,"tryCatchPattern":"if err := db.EnsureExists(ctx); err != nil {\n    if strings.Contains(err.Error(), \"no replica client configured\") {\n        return errors.New(\"initialize db.Replica.Client before EnsureExists\")\n    }\n    return err\n}","preventionTips":["Construct replicas through the config loader so the client is wired automatically.","After wiring a Replica, call Client.Init(ctx) before restore/sync.","Add an integration test asserting Replica.Client != nil after config load."],"tags":["configuration","replica","storage","restore"],"backgroundTag":"missing-required-config-field","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"}