{"record":{"id":"25a87ea628b6e0ed","repo":"AlistGo/alist","slug":"storage-not-found","errorCode":null,"errorMessage":"storage not found","messagePattern":"storage not found","errorType":"exception","errorClass":"StorageNotFound","httpStatus":null,"severity":"error","filePath":"internal/errs/errors.go","lineNumber":19,"sourceCode":"package errs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\tpkgerr \"github.com/pkg/errors\"\n)\n\nvar (\n\tNotImplement = errors.New(\"not implement\")\n\tNotSupport   = errors.New(\"not support\")\n\tRelativePath = errors.New(\"access using relative path is not allowed\")\n\n\tMoveBetweenTwoStorages = errors.New(\"can't move files between two storages, try to copy\")\n\tUploadNotSupported     = errors.New(\"upload not supported\")\n\n\tMetaNotFound     = errors.New(\"meta not found\")\n\tStorageNotFound  = errors.New(\"storage not found\")\n\tStreamIncomplete = errors.New(\"upload/download stream incomplete, possible network issue\")\n\tStreamPeekFail   = errors.New(\"StreamPeekFail\")\n\n\tUnknownArchiveFormat      = errors.New(\"unknown archive format\")\n\tWrongArchivePassword      = errors.New(\"wrong archive password\")\n\tDriverExtractNotSupported = errors.New(\"driver extraction not supported\")\n)\n\n// NewErr wrap constant error with an extra message\n// use errors.Is(err1, StorageNotFound) to check if err belongs to any internal error\nfunc NewErr(err error, format string, a ...any) error {\n\treturn fmt.Errorf(\"%w; %s\", err, fmt.Sprintf(format, a...))\n}\n\nfunc IsNotFoundError(err error) bool {\n\treturn errors.Is(pkgerr.Cause(err), ObjectNotFound) || errors.Is(pkgerr.Cause(err), StorageNotFound)\n}\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/internal/errs/errors.go#L1-L37","documentation":"StorageNotFound is a sentinel in internal/errs/errors.go returned by op.GetStorageAndActualPath when no mounted storage's base path matches the requested virtual path. In AList every virtual path is served by a storage mounted at a base path, so failure to resolve the prefix means the path belongs to no storage. errs.IsNotFoundError treats it (and ObjectNotFound) as a not-found condition.","triggerScenarios":"Any fs operation (list, get, put, other) whose path does not start with a mounted storage's base path: op.GetStorageAndActualPath(\"/nonexistent/dir/file\") returns StorageNotFound. Also triggered when the matching storage is disabled or was deleted between requests.","commonSituations":"Typos in the mount path; storage removed or disabled in the admin panel while clients still cache old links; trailing-slash or case mismatch against the configured base path; fresh installs with zero storages mounted; API consumers hardcoding paths from another instance.","solutions":["List mounted storages (admin -> Storage) and confirm one base path is a prefix of your requested path","Fix the mount path in the storage config or correct the request path to start with an existing base path","Re-enable the disabled storage that owns the path","If the storage was deleted intentionally, update clients/bookmarks to a path that still resolves"],"exampleFix":"// before\nstorage, actualPath, err := op.GetStorageAndActualPath(\"/old-mount/file.txt\")\n\n// after\nstorage, actualPath, err := op.GetStorageAndActualPath(\"/new-mount/file.txt\")\nif err != nil {\n    if errors.Is(errors.Cause(err), errs.StorageNotFound) {\n        // surface as 404, hint at mounted base paths\n    }\n}","handlingStrategy":"validation","validationCode":"// confirm some mounted storage covers the path before calling fs APIs\nif _, err := fs.List(ctx, \"/\"); err != nil { return err }","typeGuard":"func isStorageNotFound(err error) bool {\n    return err != nil && errs.IsNotFoundError(err)\n}","tryCatchPattern":"storage, actualPath, err := op.GetStorageAndActualPath(p)\nif err != nil {\n    if isStorageNotFound(err) { /* 404: no storage mounted for this prefix */ }\n    return err\n}","preventionTips":["Keep a validated allow-list of mount prefixes client-side","Re-check storage configs after enabling/disabling mounts","Return 404 for this sentinel so clients can stop retrying","Automate a startup check that every expected base path resolves"],"tags":["filesystem","storage","configuration","not-found"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}