AlistGo/alist · error
cannot move parent dir to child
Error message
cannot move parent dir to child
What it means
Move() rejects moving a directory into its own subtree: strings.HasPrefix(dstDir.GetPath(), srcObj.GetPath()) means the destination lives inside the source (e.g. moving /docs into /docs/sub). Such a move is either a no-op or would create a cycle in the git tree, so it is refused. drivers/github/driver.go:252.
Source
Thrown at drivers/github/driver.go:252
commitMessage, err := getMessage(d.mkdirMsgTmpl, &MessageTemplateVars{
UserName: getUsername(ctx),
ObjName: dirName,
ObjPath: stdpath.Join(parentDir.GetPath(), dirName),
ParentName: parentDir.GetName(),
ParentPath: parentDir.GetPath(),
}, "mkdir")
if err != nil {
return err
}
return d.commit(commitMessage, rootSha)
}
func (d *Github) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
if !d.isOnBranch {
return errors.New("cannot write to non-branch reference")
}
if strings.HasPrefix(dstDir.GetPath(), srcObj.GetPath()) {
return errors.New("cannot move parent dir to child")
}
d.commitMutex.Lock()
defer d.commitMutex.Unlock()
var rootSha string
if strings.HasPrefix(dstDir.GetPath(), stdpath.Dir(srcObj.GetPath())) { // /aa/1 -> /aa/bb/
dstOldSha, dstNewSha, ancestorOldSha, srcParentTree, err := d.copyWithoutRenewTree(srcObj, dstDir)
if err != nil {
return err
}
srcParentPath := stdpath.Dir(srcObj.GetPath())
dstRest := dstDir.GetPath()[len(srcParentPath):]
if dstRest[0] == '/' {
dstRest = dstRest[1:]
}
dstNextName, _, _ := strings.Cut(dstRest, "/")
dstNextPath := stdpath.Join(srcParentPath, dstNextName)View on GitHub (pinned to 843d9dc814)
Solutions
- Choose a destination outside the source directory's subtree (e.g. /a -> /b/a).
- If the intent was renaming, use Rename on the object instead of Move.
- Fix automation logic to reject dst paths with the src path as prefix.
Example fix
// before Move(src=/docs, dst=/docs/archive) // rejected // after Move(src=/docs, dst=/archive/docs) // valid
Defensive patterns
Strategy: validation
Validate before calling
if strings.HasPrefix(dstDir.GetPath()+"/", srcObj.GetPath()+"/") {
return errors.New("cannot move a directory into itself")
} Type guard
func isMoveIntoSelf(src, dst model.Obj) bool {
return strings.HasPrefix(stdpath.Clean(dst.GetPath())+"/", stdpath.Clean(src.GetPath())+"/")
} Prevention
- Validate src/dst path relationships before issuing Move.
- Use Rename when the goal is renaming, not relocating.
- In UIs, filter the destination picker to exclude the source's subtree.
When it happens
Trigger: Moving /a to /a/b, or /a to /a itself (path prefix collision), through the OpenList UI or API against the GitHub driver.
Common situations: User drags a folder into one of its own children by mistake; destination path typo'd to start with the source path; automation computing destination paths from source paths without excluding descendants.
Related errors
- cannot move in place
- cannot copy parent dir to child
- cannot move a submodule
- committer email is required
- committer name is required
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/194aa897bfef0d8e.
Report an issue: GitHub.