AlistGo/alist · error · NotFolder
not a folder
Error message
not a folder
What it means
NotFolder is a sentinel in internal/errs/object.go stating the resolved object exists but is not a directory. Operations that require a directory target (listing it, mkdir inside it, moving something into it) return it when the path names a file.
Source
Thrown at internal/errs/object.go:11
package errs
import (
"errors"
pkgerr "github.com/pkg/errors"
)
var (
ObjectNotFound = errors.New("object not found")
NotFolder = errors.New("not a folder")
NotFile = errors.New("not a file")
)
func IsObjectNotFound(err error) bool {
return errors.Is(pkgerr.Cause(err), ObjectNotFound)
}
View on GitHub (pinned to 843d9dc814)
Solutions
- Check the object type at that path and use the correct target (the actual folder)
- Rename or delete the conflicting file that occupies the folder name
- Invalidate the cached meta for that path if the remote was changed externally
- Add a pre-check on model.Obj.IsDir() before directory-requiring calls
Example fix
// before
err := fs.Mkdir(ctx, "/data/file.txt/newdir")
// after
obj, err := op.Get(ctx, "/data/file.txt")
if err == nil && !obj.IsDir() {
return errs.NotFolder
} Defensive patterns
Strategy: type-guard
Validate before calling
// check the target is a directory before directory-requiring ops
if obj, err := op.Get(ctx, dst); err == nil && !obj.IsDir() {
return errs.NotFolder
} Type guard
func requiresFolder(obj model.Obj) error {
if !obj.IsDir() { return errs.NotFolder }
return nil
} Try / catch
if err := fs.MakeDir(ctx, path); err != nil {
if errors.Is(errors.Cause(err), errs.NotFolder) {
// a file occupies the folder name — surface a clear message
}
} Prevention
- Pre-check IsDir() on destinations
- Avoid file/folder name collisions at the same path
- Refresh cache after replacing a folder with a file
- Validate FTP CWD targets client-side
When it happens
Trigger: Listing a path that is a regular file; creating a folder under a path that is actually a file (Mkdir); renaming/moving a file into a destination that is a file; upload with a directory component that resolves to an existing file.
Common situations: A file and intended folder share the same name (e.g. 'movie' file vs 'movie/' directory); case-insensitive storages masking a name collision; stale cache saying a path is a folder after it was replaced by a file; FTP clients issuing CWD against a file.
Related errors
- directory separator prohibited
- paths is required
- remote_path is required
- chunk_size must be positive
- name token must come before chunk token
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/a2289dd290c7d502.
Report an issue: GitHub.