{"record":{"id":"2be463948e15c852","repo":"AlistGo/alist","slug":"root-folder-s-not-exists","errorCode":null,"errorMessage":"root folder %s not exists","messagePattern":"root folder (.+?) not exists","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/local/driver.go","lineNumber":65,"sourceCode":"\tuseFFmpeg bool\n}\n\nfunc (d *Local) Config() driver.Config {\n\treturn config\n}\n\nfunc (d *Local) Init(ctx context.Context) error {\n\tif d.MkdirPerm == \"\" {\n\t\td.mkdirPerm = 0777\n\t} else {\n\t\tv, err := strconv.ParseUint(d.MkdirPerm, 8, 32)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\td.mkdirPerm = int32(v)\n\t}\n\tif !utils.Exists(d.GetRootPath()) {\n\t\treturn fmt.Errorf(\"root folder %s not exists\", d.GetRootPath())\n\t}\n\tif !filepath.IsAbs(d.GetRootPath()) {\n\t\tabs, err := filepath.Abs(d.GetRootPath())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\td.Addition.RootFolderPath = abs\n\t}\n\n\td.useFFmpeg = d.UseFFmpeg\n\n\tif d.ThumbCacheFolder != \"\" && !utils.Exists(d.ThumbCacheFolder) {\n\t\terr := os.MkdirAll(d.ThumbCacheFolder, os.FileMode(d.mkdirPerm))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\td.thumbSize = 144","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/local/driver.go#L47-L83","documentation":"Init-time configuration error of the local-storage driver: the configured root folder (RootFolderPath) does not exist on disk (utils.Exists returns false), so the mount cannot start. This is checked before anything else runs, guaranteeing fail-fast on a bad path.","triggerScenarios":"Adding/editing a local storage whose root path is misspelled, on an unmounted/unplugged drive, inside a container without the bind-mount, or using a Windows-style path on Linux (or vice versa).","commonSituations":"Docker deployments where the host folder was not mounted into the container; typo or wrong case in the path; NFS/USB drive not mounted at boot before OpenList starts; moving the data directory without updating the storage config.","solutions":["Verify the path with ls/stat on the machine/container where OpenList runs and fix the typo.","Create the directory first (mkdir -p /data/media) or point to an existing one.","In Docker, add/fix the volume mapping (-v /host/path:/container/path) and use the container path in storage config.","If the drive mounts late, ensure it is mounted before OpenList starts (systemd dependency or restart OpenList after mounting)."],"exampleFix":"# before: storage root_path = /mnt/media (does not exist in container)\n# after\ndocker run -v /host/media:/mnt/media openlist:latest\n# storage root_path = /mnt/media (now exists)","handlingStrategy":"validation","validationCode":"// Pre-flight before saving storage config\nif _, err := os.Stat(rootPath); err != nil {\n    return fmt.Errorf(\"root path %q not accessible: %w; create it or fix the mount\", rootPath, err)\n}\nif !filepath.IsAbs(rootPath) {\n    return errors.New(\"root path must be absolute\")\n}","typeGuard":"func validLocalRoot(p string) bool {\n    return filepath.IsAbs(p) && utils.Exists(p)\n}","tryCatchPattern":"if err := storage.Init(ctx); err != nil {\n    if strings.Contains(err.Error(), \"not exists\") {\n        // surface a config-form error prompting the user for the path\n        return renderPathError(err)\n    }\n}","preventionTips":["Use absolute paths in storage config; verify inside the container, not on the host.","Ensure USB/NFS mounts complete before OpenList starts.","Add docker bind mounts for every host folder referenced by local storages."],"tags":["local","filesystem","config","mount","docker","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}