benbjohnson/litestream · error

flag %q must be positioned before DB_PATH and REPLICA_URL ar

Error message

flag %q must be positioned before DB_PATH and REPLICA_URL arguments

What it means

Litestream's `replicate` command accepts DB_PATH and one or more REPLICA_URL arguments as positionals. When a flag (any argument starting with `-`) appears after the first positional argument, Go's flag package stops parsing flags, so it would be silently treated as a replica URL. ParseFlags detects this and rejects it so flags are never misinterpreted as arguments.

Source

Thrown at cmd/litestream/replicate.go:130

		// Initialize config with defaults when using command-line arguments
		c.Config = DefaultConfig()
		logLevel := "INFO"
		if *logLevelFlag != "" {
			logLevel = *logLevelFlag
			// Set env var so initLog sees CLI flag as highest priority
			os.Setenv("LOG_LEVEL", *logLevelFlag)
		}
		c.Config.Logging.Level = logLevel
		internal.InitLog(os.Stdout, logLevel, "text", false)

		dbConfig := &DBConfig{
			Path:                 fs.Arg(0),
			RestoreIfDBNotExists: *restoreIfDBNotExists,
		}
		for _, u := range fs.Args()[1:] {
			// Check if this looks like a flag that was placed after positional arguments
			if strings.HasPrefix(u, "-") {
				return fmt.Errorf("flag %q must be positioned before DB_PATH and REPLICA_URL arguments", u)
			}
			syncInterval := litestream.DefaultSyncInterval
			dbConfig.Replicas = append(dbConfig.Replicas, &ReplicaConfig{
				URL: u,
				ReplicaSettings: ReplicaSettings{
					SyncInterval: &syncInterval,
				},
			})
		}
		c.Config.DBs = []*DBConfig{dbConfig}
	}

	c.Config.ConfigPath = *configPath

	// Override config exec command, if specified.
	if *execFlag != "" {
		c.Config.Exec = *execFlag
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Move all flags before the DB_PATH argument, e.g. `litestream replicate -exec "cmd" db.sqlite s3://bucket/db`
  2. If flags belong to the config file instead, remove them from the CLI and set them in the YAML config
  3. Wrap the replica URL properly — only positional arguments (DB_PATH, REPLICA_URL...) may follow DB_PATH

Example fix

// before
litestream replicate db.sqlite s3://bucket/db -exec "myapp"
// after
litestream replicate -exec "myapp" db.sqlite s3://bucket/db
Defensive patterns

Strategy: validation

Validate before calling

// validate CLI ordering before invoking litestream
const args = process.argv.slice(2);
const firstPos = args.findIndex(a => !a.startsWith('-'));
const trailingFlag = firstPos !== -1 && args.slice(firstPos).some(a => a.startsWith('-'));
if (trailingFlag) throw new Error('all -flags must precede DB_PATH and REPLICA_URL');

Prevention

When it happens

Trigger: Running `litestream replicate db.sqlite -exec "cmd" replica_url` or any form where a `-flag` is placed after DB_PATH/REPLICA_URL positionals instead of before them.

Common situations: Users copy flag examples and append them at the end of the command line; shell scripts built by concatenating arguments put flags after URLs; muscle memory from tools that accept trailing flags.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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