{"record":{"id":"6e6d87cea4bf840a","repo":"benbjohnson/litestream","slug":"cannot-access-output-path-w","errorCode":null,"errorMessage":"cannot access output path: %w","messagePattern":"cannot access output path: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/restore.go","lineNumber":273,"sourceCode":"\tif opt.TXID != 0 {\n\t\treturn opt.TXID.String()\n\t}\n\tif opt.Follow {\n\t\treturn \"\"\n\t}\n\tinfos, err := litestream.CalcRestorePlan(ctx, r.Client, opt.TXID, opt.Timestamp, r.Logger())\n\tif err != nil || len(infos) == 0 {\n\t\treturn \"\"\n\t}\n\treturn infos[len(infos)-1].MaxTXID.String()\n}\n\nfunc (c *RestoreCommand) prepareOutputPath(path string, force bool) error {\n\tinfo, err := os.Stat(path)\n\tif os.IsNotExist(err) {\n\t\treturn nil\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"cannot access output path: %w\", err)\n\t}\n\tif info.IsDir() {\n\t\treturn fmt.Errorf(\"cannot restore, output path is a directory: %s\", path)\n\t}\n\n\tif info.Size() > 0 && !force {\n\t\treturn fmt.Errorf(\"cannot restore, output path already exists and is not empty: %s. Use -force to overwrite\", path)\n\t}\n\n\tfor _, sidecarPath := range []string{path + \"-wal\", path + \"-shm\", path + \"-journal\"} {\n\t\tif _, err := os.Stat(sidecarPath); err == nil && !force {\n\t\t\treturn fmt.Errorf(\"cannot restore, SQLite sidecar path already exists: %s. Use -force to overwrite\", sidecarPath)\n\t\t} else if err != nil && !os.IsNotExist(err) {\n\t\t\treturn fmt.Errorf(\"cannot access SQLite sidecar path: %w\", err)\n\t\t}\n\t}\n\n\tfor _, removePath := range []string{path, path + \"-wal\", path + \"-shm\", path + \"-journal\"} {","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/restore.go#L255-L291","documentation":"prepareOutputPath calls os.Stat on the requested restore output path and wraps any unexpected stat failure with this error. It means the OS could not stat the path for a reason other than non-existence — most commonly a permission problem on a parent directory or an I/O error. Non-existence is explicitly tolerated (restore will create the file), so this signals a real environmental problem.","triggerScenarios":"os.Stat(outputPath) returns an error that is not os.IsNotExist — e.g. a parent directory lacks search permission, the path component is not a directory, or an I/O error occurs while accessing the path.","commonSituations":"Restoring into a directory the current user cannot traverse (e.g. /var/lib owned by root); a typo'd path where a component is a file, not a directory; a dangling mount or full/EIO disk.","solutions":["Check permissions on every path component of the output path (ls -ld on each parent) and fix with chown/chmod","Verify all intermediate path components are directories, not files","Check `dmesg`/disk health if a filesystem error is suspected","Run the restore as a user with access to the target location"],"exampleFix":"// before\nlitestream restore -o /var/lib/db/app.db replica\ncannot access output path: stat /var/lib/db/app.db: permission denied\n// after\nsudo chown litestream:litestream /var/lib/db\nlitestream restore -o /var/lib/db/app.db replica","handlingStrategy":"validation","validationCode":"import \"os\"\nimport \"path/filepath\"\n\n// Ensure the output location is statable and writable before restoring.\ndir := filepath.Dir(outputPath)\nif _, err := os.Stat(dir); err != nil {\n    return fmt.Errorf(\"output dir not accessible: %w\", err)\n}\nf, err := os.CreateTemp(dir, \".restore-check\")\nif err != nil {\n    return fmt.Errorf(\"output dir not writable: %w\", err)\n}\nf.Close()\nos.Remove(f.Name())","typeGuard":null,"tryCatchPattern":"if err := cmd.Run(ctx); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        return fmt.Errorf(\"check access to %s: %w\", pe.Path, pe.Err)\n    }\n    return err\n}","preventionTips":["Run litestream as a user with traverse/write access to the output directory","Verify the full output path with `ls -ld` of each component before restoring","Avoid paths containing non-directory components or dangling mounts","Test output location writability with `touch <dir>/.probe` first"],"tags":["filesystem","permissions","restore"],"backgroundTag":"file-open-failed","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"}