{"record":{"id":"7f4c00e664d2db50","repo":"benbjohnson/litestream","slug":"replica-sync-w","errorCode":null,"errorMessage":"replica sync: %w","messagePattern":"replica sync: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":725,"sourceCode":"\treturn SyncStatus{\n\t\tLocalTXID:  localPos.TXID,\n\t\tRemoteTXID: remotePos.TXID,\n\t\tInSync:     localPos.TXID > 0 && localPos.TXID == remotePos.TXID,\n\t}, nil\n}\n\n// SyncAndWait performs a full sync: WAL to LTX files, then LTX files to remote\n// replica. Blocks until both stages complete.\nfunc (db *DB) SyncAndWait(ctx context.Context) error {\n\tif db.Replica == nil {\n\t\treturn fmt.Errorf(\"no replica configured\")\n\t}\n\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) {","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L707-L743","documentation":"DB.SyncAndWait() wraps an error from the second stage, db.Replica.Sync(ctx), with \"replica sync\". This stage uploads local LTX files to the remote replica; failure means the remote replication (storage backend write) failed after the local sync succeeded.","triggerScenarios":"Calling db.SyncAndWait(ctx) when Replica.Sync fails: upload errors to S3/GCS/Azure/file storage, authentication failures, network timeouts, conditional-write (lease) conflicts with another litestream process, or the replica client not initialized.","commonSituations":"Expired cloud credentials; bucket permissions changed (PutObject denied); another replica process holding a lease (lease conflict); network partition during upload; misconfigured endpoint for S3-compatible providers (MinIO, R2).","solutions":["Unwrap the error to find the failing storage operation.","Verify write permissions and credentials on the replica destination.","Check for another litestream process replicating the same database (lease conflicts); stop duplicates.","Retry on transient network errors — SyncAndWait is safe to call again; LTX uploads are idempotent per TXID."],"exampleFix":"// before\nif err := db.SyncAndWait(ctx); err != nil {\n    return err // opaque\n}\n// after\nif err := db.SyncAndWait(ctx); err != nil {\n    if litestream.IsRetentionConflict(err) { /* handle lease conflict */ }\n    return fmt.Errorf(\"sync and wait: %w\", err) // keep chain for diagnosis\n}","handlingStrategy":"retry","validationCode":"// preflight a write to the replica destination with the same credentials\n// before relying on SyncAndWait for critical paths","typeGuard":null,"tryCatchPattern":"if err := db.SyncAndWait(ctx); err != nil {\n    if isTransientNetwork(err) {\n        time.Sleep(backoff)\n        return db.SyncAndWait(ctx) // safe to retry\n    }\n    return err\n}","preventionTips":["Rotate and validate cloud credentials before expiry.","Grant PutObject on the replica prefix to the litestream identity.","Run exactly one litestream process per database to avoid lease conflicts.","Retry SyncAndWait on transient errors — it is idempotent per TXID."],"tags":["network","storage","replication","error-wrapping"],"backgroundTag":"api-request-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"}