{"record":{"id":"df8c2179c027c2fb","repo":"benbjohnson/litestream","slug":"file-replica-path-required","errorCode":null,"errorMessage":"file replica path required","messagePattern":"file replica path required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":1437,"sourceCode":"\n// newFileReplicaClientFromConfig returns a new instance of file.ReplicaClient built from config.\nfunc newFileReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *file.ReplicaClient, err error) {\n\t// Ensure URL & path are not both specified.\n\tif c.URL != \"\" && c.Path != \"\" {\n\t\treturn nil, fmt.Errorf(\"cannot specify url & path for file replica\")\n\t}\n\n\t// Parse configPath from URL, if specified.\n\tconfigPath := c.Path\n\tif c.URL != \"\" {\n\t\tif _, _, configPath, err = litestream.ParseReplicaURL(c.URL); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Ensure path is set explicitly or derived from URL field.\n\tif configPath == \"\" {\n\t\treturn nil, fmt.Errorf(\"file replica path required\")\n\t}\n\n\t// Expand home prefix and return absolute path.\n\tif configPath, err = expand(configPath); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Instantiate replica and apply time fields, if set.\n\tclient := file.NewReplicaClient(configPath)\n\tclient.Replica = r\n\treturn client, nil\n}\n\n// NewS3ReplicaClientFromConfig returns a new instance of s3.ReplicaClient built from config.\n// Exported for testing.\nfunc NewS3ReplicaClientFromConfig(c *ReplicaConfig, _ *litestream.Replica) (_ *s3.ReplicaClient, err error) {\n\t// Ensure URL & constituent parts are not both specified.\n\tif c.URL != \"\" && c.Path != \"\" {","sourceCodeStart":1419,"sourceCodeEnd":1455,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L1419-L1455","documentation":"newFileReplicaClientFromConfig found neither url nor path set on the file replica config, so there is no directory to replicate into. It is the guard after the both-set check: the replica destination is simply missing.","triggerScenarios":"A file replica with neither `path` nor a `url` containing a path component (e.g. `url: file://` or `url: file://host` with empty path), so configPath stays \"\".","commonSituations":"Config entry `- url: file://` with trailing slashes stripped by an editor; a replica block that only sets `type: file` with no destination; env-var expansion in the path resolving to empty.","solutions":["Set `path: /absolute/or/~/relative/dir` on the file replica","Or set a full `url: file:///backups/db` including the path part","Check that any env var used in the path is set at launch"],"exampleFix":"# before\nreplicas:\n  - url: file://\n# after\nreplicas:\n  - url: file:///var/backups/db","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(r.URL)\nif r.Path == \"\" && (u == nil || u.Path == \"\" || u.Path == \"/\") {\n    return errors.New(\"file replica requires path or url with a path component\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always give file replicas an explicit absolute path","Avoid bare `file://` URLs without a path","Check env-expanded path values are non-empty before launch"],"tags":["config","replica","file","required-field"],"backgroundTag":"missing-required-config-field","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}