benbjohnson/litestream · error

too many arguments

Error message

too many arguments

What it means

The `litestream register` command's Run enforces argument arity: after flags, exactly one positional argument (the database path) is accepted. Supplying more than one positional argument returns this usage error.

Source

Thrown at cmd/litestream/register.go:37

func (c *RegisterCommand) Run(ctx context.Context, args []string) error {
	fs := flag.NewFlagSet("litestream-register", flag.ContinueOnError)
	timeout := fs.Int("timeout", 30, "timeout in seconds")
	socketPath := fs.String("socket", "/var/run/litestream.sock", "control socket path")
	replicaFlag := fs.String("replica", "", "replica URL (e.g., s3://bucket/prefix, file:///backup/path)")
	jsonOutput := fs.Bool("json", false, "output raw JSON")
	fs.Usage = c.Usage
	if err := fs.Parse(args); err != nil {
		return err
	}

	if fs.NArg() == 0 {
		return &usageError{
			message: "database path required",
			hint:    "litestream register -replica s3://bucket/prefix /path/to/db",
		}
	}
	if fs.NArg() > 1 {
		return fmt.Errorf("too many arguments")
	}
	if *replicaFlag == "" {
		return &usageError{
			message: "-replica is required",
			hint:    "litestream register -replica s3://bucket/prefix /path/to/db",
		}
	}
	if *timeout <= 0 {
		return fmt.Errorf("timeout must be greater than 0")
	}

	dbPath := fs.Arg(0)
	replicaURL := *replicaFlag

	// Create HTTP client that connects via Unix socket with timeout.
	clientTimeout := time.Duration(*timeout) * time.Second
	client := &http.Client{
		Timeout: clientTimeout,

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Pass exactly one database path per invocation; run the command once per database.
  2. Quote globs or check what the shell expanded (`echo /path/*.db`) to avoid multiple paths.
  3. Reorder options so all flags come before the single positional DB path.

Example fix

// before
litestream register -replica s3://bucket/prefix db1.sqlite db2.sqlite
// after
litestream register -replica s3://bucket/prefix db1.sqlite
litestream register -replica s3://bucket/prefix db2.sqlite
Defensive patterns

Strategy: validation

Validate before calling

// Ensure exactly one positional arg is passed to register
args := flagArgs
if len(args) != 1 {
    return fmt.Errorf("register takes exactly one db path, got %d", len(args))
}

Try / catch

if err := runRegister(args); err != nil {
    var ue *usageError
    if errors.As(err, &ue) {
        fmt.Fprintf(os.Stderr, "usage: %s\n", ue.hint)
        os.Exit(2)
    }
}

Prevention

When it happens

Trigger: Running `litestream register -replica s3://bucket/prefix db1.sqlite db2.sqlite` or passing extra positional tokens (e.g. trailing flags misplaced so they count as args).

Common situations: Trying to register multiple databases in one command; shell globbing expanding into several paths; pasting a command with an extra stray argument.

Understand the failure class

Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.

Related errors


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