AlistGo/alist · error

move operation failed with code: %d

Error message

move operation failed with code: %d

What it means

Proton returned 200 for the move but the body's Code is not 1000. The numeric code carries the real reason: invalid/expired token, invalid hashes, target-parent not writable, or passphrase re-encryption rejected (bad NodePassphrase).

Source

Thrown at drivers/proton_drive/util.go:726

	httpReq.Header.Set("X-Pm-Appversion", d.webDriveAV)
	httpReq.Header.Set("X-Pm-Drive-Sdk-Version", d.sdkVersion)
	httpReq.Header.Set("X-Pm-Uid", d.credentials.UID)
	httpReq.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(httpReq)
	if err != nil {
		return fmt.Errorf("failed to execute move request: %w", err)
	}
	defer resp.Body.Close()

	var moveResp RenameResponse
	if err := json.NewDecoder(resp.Body).Decode(&moveResp); err != nil {
		return fmt.Errorf("failed to decode move response: %w", err)
	}

	if moveResp.Code != 1000 {
		return fmt.Errorf("move operation failed with code: %d", moveResp.Code)
	}

	return nil
}

func (d *ProtonDrive) DirectMove(ctx context.Context, srcObj model.Obj, dstDir model.Obj) (model.Obj, error) {
	//fmt.Printf("DEBUG DirectMove: srcPath=%s, dstPath=%s", srcObj.GetPath(), dstDir.GetPath())

	srcLink, err := d.searchByPath(ctx, srcObj.GetPath(), srcObj.IsDir())
	if err != nil {
		return nil, fmt.Errorf("failed to find source: %w", err)
	}

	var dstParentLinkID string
	if dstDir.GetPath() == "/" {
		dstParentLinkID = d.RootLink.LinkID
	} else {
		dstLink, err := d.searchByPath(ctx, dstDir.GetPath(), true)

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Log moveResp.Code and map known codes (auth vs hash vs permission) instead of showing only the number
  2. For hash errors, re-fetch the link, regenerate hashes and passphrase, retry once
  3. For permission codes, fail fast with a permission error
  4. Use the official proton-go move API which encodes these failure modes properly
Defensive patterns

Strategy: try-catch

Type guard

func isMoveCodeErr(err error) (code int, ok bool) {
    var n int
    if _, e := fmt.Sscanf(err.Error(), "move operation failed with code: %d", &n); e == nil { return n, true }
    return 0, false
}

Try / catch

if code, ok := isMoveCodeErr(err); ok {
    if isAuthCode(code) { refreshCreds(); retry() }
    if isPermissionCode(code) { return fmt.Errorf("no write access to destination") }
    if isHashCode(code) { refetchLink(); regenerateHashesAndPassphrase(); retryOnce() }
}

Prevention

When it happens

Trigger: Moving into a share where the account lacks write permission; NodePassphrase re-encrypted with the wrong destination keyring; stale OriginalHash; name-hash collision (duplicate name) in the destination folder.

Common situations: Moves into folders shared read-only; cross-share moves where the destination parent keyring could not be derived; concurrent clients mutating the same tree; keyring/address-key drift after password reset (old keys revoked).

Related errors


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