{"record":{"id":"c140d94e9fb5c1f6","repo":"benbjohnson/litestream","slug":"cannot-specify-a-replica-url-and-the-config-flag-c140d9","errorCode":null,"errorMessage":"cannot specify a replica URL and the -config flag","messagePattern":"cannot specify a replica URL and the -config flag","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/restore.go","lineNumber":98,"sourceCode":"\t\topt.IntegrityCheck = litestream.IntegrityCheckQuick\n\tcase \"full\":\n\t\topt.IntegrityCheck = litestream.IntegrityCheckFull\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid -integrity-check value: %s\", *integrityCheck)\n\t}\n\n\t// Parse timestamp, if specified.\n\tif *timestampStr != \"\" {\n\t\tif opt.Timestamp, err = time.Parse(time.RFC3339, *timestampStr); err != nil {\n\t\t\treturn errors.New(\"invalid -timestamp, must specify in ISO 8601 format (e.g. 2000-01-01T00:00:00Z)\")\n\t\t}\n\t}\n\n\t// Determine replica to restore from.\n\tvar r *litestream.Replica\n\tif litestream.IsURL(fs.Arg(0)) {\n\t\tif *configPath != \"\" {\n\t\t\treturn fmt.Errorf(\"cannot specify a replica URL and the -config flag\")\n\t\t}\n\t\tif r, err = c.loadFromURL(ctx, fs.Arg(0), *ifDBNotExists, &opt); errors.Is(err, errSkipDBExists) {\n\t\t\tslog.Info(\"database already exists, skipping\")\n\t\t\treturn nil\n\t\t} else if err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif *configPath == \"\" {\n\t\t\t*configPath = DefaultConfigPath()\n\t\t}\n\t\tif r, err = c.loadFromConfig(ctx, fs.Arg(0), *configPath, !*noExpandEnv, *ifDBNotExists, &opt); errors.Is(err, errSkipDBExists) {\n\t\t\tslog.Info(\"database already exists, skipping\")\n\t\t\treturn nil\n\t\t} else if err != nil {\n\t\t\treturn err\n\t\t}\n\t}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/restore.go#L80-L116","documentation":"`restore` supports two mutually exclusive ways to pick the restore source: a positional replica URL argument, or the -config flag pointing at a config file. Supplying both is ambiguous, so the command rejects it up front with this error. Only when the first positional arg is a URL (litestream.IsURL) is the -config conflict checked.","triggerScenarios":"`litestream restore s3://bucket/prefix -config litestream.yml` — a replica URL as arg 0 while -config is also set.","commonSituations":"Users with a config file who also paste a replica URL from docs/scripts; automations that always append -config even when a URL form is used; shell scripts assembling the command from multiple variables.","solutions":["Drop -config when restoring directly from a replica URL","Or drop the URL argument and instead select the db (and replica) via the config file with a db path argument","If the URL comes from a variable that may be empty, guard the script so -config is only added when no URL is present"],"exampleFix":"// before\nlitestream restore s3://bucket/prefix -config /etc/litestream.yml -o out.db\n// after\nlitestream restore s3://bucket/prefix -o out.db","handlingStrategy":"validation","validationCode":"if replicaURL != \"\" && configPath != \"\" {\n    return fmt.Errorf(\"pass either a replica URL or -config, not both\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In scripts, add -config only when no URL argument is present","Document one canonical restore style per runbook","Keep -config out of generic wrapper functions that also accept URLs"],"tags":["cli","flags","mutually-exclusive","restore"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}