benbjohnson/litestream · error

output path required

Error message

output path required

What it means

Replica.Restore validates RestoreOptions before doing any work. If opt.OutputPath is empty there is no destination for the restored database file, so restore immediately fails with this error. It is a pure argument-validation error — no storage or database access happens first.

Source

Thrown at replica.go:611

	return updatedAt, nil
}

// Replica restores the database from a replica based on the options given.
// This method will restore into opt.OutputPath, if specified, or into the
// DB's original database path. It can optionally restore from a specific
// replica or it will automatically choose the best one. Finally,
// a timestamp can be specified to restore the database to a specific
// point-in-time.
//
// When the replica contains both v0.3.x and LTX format backups, this method
// compares snapshots from both formats and uses whichever has the better backup:
// - With timestamp: uses the format with the most recent snapshot before timestamp
// - Without timestamp: uses the format with the most recent backup overall
func (r *Replica) Restore(ctx context.Context, opt RestoreOptions) (err error) {
	// Validate options.
	if opt.OutputPath == "" {
		return fmt.Errorf("output path required")
	} else if opt.TXID != 0 && !opt.Timestamp.IsZero() {
		return fmt.Errorf("cannot specify index & timestamp to restore")
	} else if opt.Follow && opt.TXID != 0 {
		return fmt.Errorf("cannot use follow mode with -txid")
	} else if opt.Follow && !opt.Timestamp.IsZero() {
		return fmt.Errorf("cannot use follow mode with -timestamp")
	} else if opt.IntegrityCheck != IntegrityCheckNone && opt.IntegrityCheck != IntegrityCheckQuick && opt.IntegrityCheck != IntegrityCheckFull {
		return fmt.Errorf("unsupported integrity check mode: %d", opt.IntegrityCheck)
	}

	// In follow mode, if the database already exists, attempt crash recovery
	// by reading the last applied TXID from the sidecar file.
	if opt.Follow {
		if _, statErr := os.Stat(opt.OutputPath); statErr == nil {
			txid, readErr := ReadTXIDFile(opt.OutputPath)
			if readErr != nil {
				return fmt.Errorf("read txid file for crash recovery: %w", readErr)
			}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Set OutputPath in RestoreOptions to the target database file path before calling Restore.
  2. If using the CLI, pass the -o flag with a writable destination path.
  3. Ensure the destination directory exists and is writable before restoring.

Example fix

// before
err := replica.Restore(ctx, litestream.RestoreOptions{TXID: txid})

// after
err := replica.Restore(ctx, litestream.RestoreOptions{
    TXID:       txid,
    OutputPath: "/var/lib/app/db.sqlite",
})
Defensive patterns

Strategy: validation

Validate before calling

if opt.OutputPath == "" {
    return fmt.Errorf("OutputPath must be set before Restore")
}
if err := os.MkdirAll(filepath.Dir(opt.OutputPath), 0o755); err != nil {
    return err
}

Try / catch

if err := replica.Restore(ctx, opt); err != nil && strings.Contains(err.Error(), "output path required") {
    // fix option construction; this is a programmer/config error, not transient
}

Prevention

When it happens

Trigger: Calling Replica.Restore (directly or via Run, EnsureExists, tests) with RestoreOptions that leaves OutputPath unset — e.g. programmatically building RestoreOptions{} without setting OutputPath.

Common situations: Programmatic restore code constructing RestoreOptions with only TXID/Timestamp; a CLI path that failed to bind the -o flag value; EnsureExists invoked with a zero-value options struct.

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/6f7810b92ff42ec4. Report an issue: GitHub.