benbjohnson/litestream · error
target time required
Error message
target time required
What it means
Returned by VFSFile.SetTargetTime (time-travel read view) when the caller passes a zero time.Time. The method rebuilds the page index at a specific point in time; a zero timestamp is meaningless for CalcRestorePlan, so it is rejected up front with this sentinel error.
Source
Thrown at vfs.go:1253
f.syncStop = make(chan struct{})
stopCh := f.syncStop
tickerCh := f.syncTicker.C
f.wg.Add(1)
go func() { defer f.wg.Done(); f.syncLoop(stopCh, tickerCh) }()
}
// Start compaction monitors if enabled
if f.compactor != nil && f.vfs != nil {
f.startCompactionMonitors()
}
return nil
}
// SetTargetTime rebuilds the page index to view the database at a specific time.
func (f *VFSFile) SetTargetTime(ctx context.Context, timestamp time.Time) error {
if timestamp.IsZero() {
return fmt.Errorf("target time required")
}
infos, err := CalcRestorePlan(ctx, f.client, 0, timestamp, f.logger)
if err != nil {
return fmt.Errorf("cannot calc restore plan: %w", err)
} else if len(infos) == 0 {
return fmt.Errorf("no backup files available")
}
// Disable hydrated reads during time travel - hydrated file is at latest state
if f.hydrator != nil && f.hydrator.Complete() {
f.hydrator.Disable()
f.logger.Debug("hydration disabled for time travel", "target", timestamp)
}
return f.rebuildIndex(ctx, infos, ×tamp)
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check timestamp.IsZero() before calling SetTargetTime and skip/branch to ResetTime when unset
- Parse the user-supplied time with error handling so a parse failure doesn't silently yield a zero time
- Use ResetTime(ctx) when you actually want the latest state instead of a target time
Example fix
// before
var target time.Time
file.SetTargetTime(ctx, target) // panics-free but errors
// after
if target.IsZero() {
err = file.ResetTime(ctx)
} else {
err = file.SetTargetTime(ctx, target)
} Defensive patterns
Strategy: validation
Validate before calling
if targetTime.IsZero() { return errors.New("target time required before SetTargetTime") } Type guard
func hasTarget(t time.Time) bool { return !t.IsZero() } Try / catch
if err := file.SetTargetTime(ctx, t); err != nil {
if err.Error() == "target time required" {
return file.ResetTime(ctx) // fall back to latest
}
return err
} Prevention
- Check timestamps parsed from user input/JSON for zero values
- Use pointers or explicit 'set' flags for optional time config
- Prefer ResetTime when latest state is intended
When it happens
Trigger: Calling SetTargetTime(ctx, time.Time{}) — e.g. an unset struct field, a failed JSON/DB decode of the target time, or a var declared without initialization — instead of a real restore timestamp.
Common situations: App config where the restore-time option is optional and left empty; deserialization of a missing timestamp field defaulting to the zero value; passing time.Now() result stored in a zero-valued variable due to an earlier error.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- invalid -timestamp, must specify in ISO 8601 format (e.g. 20
- timestamp does not exist
- cannot specify both TXID & timestamp to restore
- cannot calc restore plan: %w
- no backup files available
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/102ad1c3004dc117.
Report an issue: GitHub.