{"record":{"id":"c62255788315e73e","repo":"benbjohnson/litestream","slug":"v0-3-x-time-bounds-w","errorCode":null,"errorMessage":"v0.3.x time bounds: %w","messagePattern":"v0\\.3\\.x time bounds: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":573,"sourceCode":"\t\t\treturn createdAt, updatedAt, err\n\t\t}\n\t}\n\treturn createdAt, updatedAt, nil\n}\n\n// CalcRestoreTarget returns a target time restore from.\nfunc (r *Replica) CalcRestoreTarget(ctx context.Context, opt RestoreOptions) (updatedAt time.Time, err error) {\n\t// Determine the replicated time bounds from LTX files.\n\tcreatedAt, updatedAt, err := r.TimeBounds(ctx)\n\tif err != nil {\n\t\treturn time.Time{}, fmt.Errorf(\"created at: %w\", err)\n\t}\n\n\t// Also check v0.3.x time bounds if client supports it.\n\tif client, ok := r.Client.(ReplicaClientV3); ok {\n\t\tv3CreatedAt, v3UpdatedAt, err := r.TimeBoundsV3(ctx, client)\n\t\tif err != nil {\n\t\t\treturn time.Time{}, fmt.Errorf(\"v0.3.x time bounds: %w\", err)\n\t\t}\n\t\t// Extend time bounds to include v0.3.x backups.\n\t\tif !v3CreatedAt.IsZero() && (createdAt.IsZero() || v3CreatedAt.Before(createdAt)) {\n\t\t\tcreatedAt = v3CreatedAt\n\t\t}\n\t\tif !v3UpdatedAt.IsZero() && (updatedAt.IsZero() || v3UpdatedAt.After(updatedAt)) {\n\t\t\tupdatedAt = v3UpdatedAt\n\t\t}\n\t}\n\n\t// Skip if it does not contain timestamp.\n\tif !opt.Timestamp.IsZero() {\n\t\tif createdAt.IsZero() && updatedAt.IsZero() {\n\t\t\treturn time.Time{}, fmt.Errorf(\"no backups found\")\n\t\t}\n\t\tif opt.Timestamp.Before(createdAt) || opt.Timestamp.After(updatedAt) {\n\t\t\treturn time.Time{}, fmt.Errorf(\"timestamp does not exist\")\n\t\t}","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L555-L591","documentation":"When the replica client supports the legacy v0.3.x format (ReplicaClientV3), CalcRestoreTarget also computes time bounds from old-generation backups via TimeBoundsV3. Failure of that legacy enumeration is wrapped with this message, separate from the current-format 'created at' error, so you know which backup format's metadata could not be read.","triggerScenarios":"CalcRestoreTarget is called on a replica whose Client implements ReplicaClientV3, and TimeBoundsV3 fails reading legacy generation metadata (missing/invalid generations, listing errors, unreadable legacy super-records).","commonSituations":"Replicas upgraded from litestream v0.3.x with partially deleted or damaged legacy _ generations; storage listing failures; legacy timestamps records missing or corrupted after manual storage cleanup.","solutions":["Read the wrapped cause to see which legacy generation/metadata read failed.","If legacy v0.3.x backups are no longer needed, remove the legacy generations or use a client without ReplicaClientV3 support so they are skipped.","Restore access to / re-upload intact legacy objects, or rely on current LTX backups only.","Run `litestream ltx` to verify what the replica can currently see."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// detect legacy support before relying on v0.3.x bounds\nif _, ok := replica.Client.(litestream.ReplicaClientV3); ok {\n    // legacy metadata will be read; validate legacy generations exist\n}","typeGuard":"if v3, ok := replica.Client.(litestream.ReplicaClientV3); ok {\n    // client supports legacy format\n}","tryCatchPattern":"target, err := replica.CalcRestoreTarget(ctx, opt)\nif err != nil && strings.Contains(err.Error(), \"v0.3.x time bounds\") {\n    // legacy metadata unreadable: decide whether legacy backups are still needed\n}","preventionTips":["After migrating from v0.3.x, either keep legacy generations intact or remove them deliberately","Don't manually prune generation directories in replica storage","Test restores after version upgrades"],"tags":["restore","legacy-v03","migration"],"backgroundTag":"database-query-failed","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"}