AlistGo/alist · warning

cannot move in place

Error message

cannot move in place

What it means

In Move()'s upward-move branch, after stripping the destination prefix from the source path the remainder contains no '/' — meaning the source is a direct child of the destination (e.g. /aa/1 -> /aa/). That is a move in place with no rename component, which the tree-rewrite logic cannot express, so it errors. drivers/github/driver.go:342.

Source

Thrown at drivers/github/driver.go:342

		if len(srcParentTree.Trees) == 1 {
			delSrcTree = append(delSrcTree, map[string]string{
				"path":    ".gitkeep",
				"mode":    "100644",
				"type":    "blob",
				"content": "",
			})
		}
		srcParentNewSha, err := d.newTree(srcParentOldSha, delSrcTree)
		if err != nil {
			return err
		}
		srcRest := srcObj.GetPath()[len(dstDir.GetPath()):]
		if srcRest[0] == '/' {
			srcRest = srcRest[1:]
		}
		srcNextName, _, ok := strings.Cut(srcRest, "/")
		if !ok { // /aa/1 -> /aa/
			return errors.New("cannot move in place")
		}
		srcNextPath := stdpath.Join(dstDir.GetPath(), srcNextName)
		srcNextTreeSha, err := d.renewParentTrees(srcParentPath, srcParentOldSha, srcParentNewSha, srcNextPath)
		if err != nil {
			return err
		}

		ancestorTree, ancestorOldSha, err := d.getTreeDirectly(dstDir.GetPath())
		if err != nil {
			return err
		}
		var srcNextTree *TreeObjReq = nil
		for _, t := range ancestorTree.Trees {
			if t.Path == srcNextName {
				srcNextTree = &t.TreeObjReq
				srcNextTree.Sha = srcNextTreeSha
				break
			}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Skip the move entirely — the object is already where the request wants it.
  2. If a rename was intended, call Rename instead of Move.
  3. Fix callers to filter out moves where dstDir == parent of srcObj.

Example fix

// before
Move(src=/aa/1, dst=/aa) // error: cannot move in place

// after
// no-op: already in place; or rename:
Rename(src=/aa/1, newName="1-renamed")
Defensive patterns

Strategy: validation

Validate before calling

if stdpath.Clean(dstDir.GetPath()) == stdpath.Dir(srcObj.GetPath()) {
    // already a direct child of destination: nothing to do
    return nil
}

Prevention

When it happens

Trigger: Moving an object to a directory that is already its direct parent — dst == stdpath.Dir(src) effectively — hitting the !ok branch after strings.Cut.

Common situations: Drag-and-drop onto the object's own parent folder in the UI; automation generating a move to the containing directory as a no-op.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/a132209d64bb15ce. Report an issue: GitHub.