AlistGo/alist · error

wukong move failed: code=%d message=%s

Error message

wukong move failed: code=%d message=%s

What it means

Thrown by the Wukong driver's Move after POSTing file_id_list plus new_father_id to /netdisk/user_file/move_file. The transport call succeeded but resp.Code is non-zero: the API rejected the move operation. Typical causes are invalid/missing file IDs, target directory problems, or insufficient permission on the destination.

Source

Thrown at drivers/wukong/driver.go:242

	var resp rawResp
	_, err := d.client.R().
		SetContext(ctx).
		SetQueryParams(map[string]string{
			"aid":             d.Aid,
			"device_platform": "web",
			"language":        d.Language,
		}).
		SetBody(map[string]any{
			"file_id_list":  []any{asIDValue(srcID)},
			"new_father_id": asIDValue(dstID),
		}).
		SetResult(&resp).
		Post("/netdisk/user_file/move_file")
	if err != nil {
		return err
	}
	if resp.Code != 0 {
		return fmt.Errorf("wukong move failed: code=%d message=%s", resp.Code, resp.Message)
	}
	return nil
}

func (d *Wukong) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
	srcID := srcObj.GetID()
	if srcID == "" {
		return errors.New("missing file id")
	}

	var resp rawResp
	_, err := d.client.R().
		SetContext(ctx).
		SetQueryParams(map[string]string{
			"aid":             d.Aid,
			"device_platform": "web",
			"language":        d.Language,
		}).

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-List both the source parent and destination directory to obtain fresh IDs, then retry the move
  2. Check that srcID and dstID are non-empty and that dstDir is a folder (not a file) before calling Move
  3. Refresh Wukong credentials if the business code indicates auth failure
  4. Guard against moving a directory into itself or one of its descendants before issuing the API call

Example fix

// before
func (d *Wukong) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
    // direct API call
}

// after
func (d *Wukong) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
    if srcObj.GetID() == "" || dstDir.GetID() == "" {
        return errors.New("missing source or destination id")
    }
    if srcObj.GetID() == dstDir.GetID() || isDescendant(ctx, d, srcObj, dstDir) {
        return errors.New("cannot move a folder into itself")
    }
    // direct API call
}
Defensive patterns

Strategy: validation

Validate before calling

if srcObj.GetID() == "" || dstDir.GetID() == "" {
    return errors.New("move aborted: missing source or destination id")
}
if srcObj.GetID() == dstDir.GetID() {
    return errors.New("move aborted: source and destination are the same")
}

Try / catch

if err := d.Move(ctx, srcObj, dstDir); err != nil {
    if isWukongAuthErr(err) { // session code: refresh and retry once
        if rerr := d.refreshSession(ctx); rerr == nil {
            return d.Move(ctx, srcObj, dstDir)
        }
    }
    return err
}

Prevention

When it happens

Trigger: Moving an object whose GetID() is empty or stale (file deleted remotely); moving into a destination dir ID that no longer exists; moving into its own subtree; moving a file the account does not own; session expired.

Common situations: Stale listing cache in the frontend showing files already deleted from the Wukong web pan; drag-and-drop move where dstDir was concurrently renamed; copy tasks racing each other with the same source; account permission changed on a shared folder.

Related errors


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