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
- Move all flags before the DB_PATH argument, e.g. `litestream replicate -exec "cmd" db.sqlite s3://bucket/db`
- If flags belong to the config file instead, remove them from the CLI and set them in the YAML config
- 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
- Always place flags before positional DB_PATH and REPLICA_URL arguments
- Build commands from arrays (argv lists) rather than string concatenation
- Add a shell wrapper/script that enforces argument order
- Consult `litestream replicate -h` for the accepted positional layout
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
- invalid target size: %w
- config file not found
- invalid -timestamp, must specify in ISO 8601 format (e.g. 20
- database path required
- database does not exist: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/5655542f7ac6732e.
Report an issue: GitHub.