AlistGo/alist · error

rename failed with code %d

Error message

rename failed with code %d

What it means

Proton answered 200 but the JSON body's Code field is not 1000 (the success code). This is the API-level rejection of the rename: common Proton codes include 401-equivalents (invalid token), 2029/2028-style hash mismatches (Hash or OriginalHash wrong), and duplicate-name conflicts in the target folder.

Source

Thrown at drivers/proton_drive/util.go:666

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

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("rename failed with status %d", resp.StatusCode)
	}

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

	if renameResp.Code != 1000 {
		return fmt.Errorf("rename failed with code %d", renameResp.Code)
	}

	return nil
}

func (d *ProtonDrive) executeMoveAPI(ctx context.Context, linkID string, req MoveRequest) error {
	//fmt.Printf("DEBUG Move Request - Name: %s\n", req.Name)
	//fmt.Printf("DEBUG Move Request - Hash: %s\n", req.Hash)
	//fmt.Printf("DEBUG Move Request - OriginalHash: %s\n", req.OriginalHash)
	//fmt.Printf("DEBUG Move Request - ParentLinkID: %s\n", req.ParentLinkID)

	//fmt.Printf("DEBUG Move Request - Name length: %d\n", len(req.Name))
	//fmt.Printf("DEBUG Move Request - NameSignatureEmail: %s\n", req.NameSignatureEmail)
	//fmt.Printf("DEBUG Move Request - ContentHash: %v\n", req.ContentHash)
	//fmt.Printf("DEBUG Move Request - NodePassphrase length: %d\n", len(req.NodePassphrase))
	//fmt.Printf("DEBUG Move Request - NodePassphraseSignature length: %d\n", len(req.NodePassphraseSignature))

	//fmt.Printf("DEBUG Move Request - SrcLinkID: %s\n", linkID)

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-fetch the link (fresh OriginalHash) and recompute both hashes, then retry once
  2. If the code indicates a name conflict, auto-suffix or surface a 'name exists' error to the user
  3. Map and log the numeric code so 401 vs hash-mismatch vs conflict is distinguishable
  4. Move renames onto the official proton-go API client which decodes these codes for you
Defensive patterns

Strategy: retry

Type guard

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

Try / catch

if code, ok := isRenameCodeErr(err); ok {
    if isAuthCode(code) { refreshCreds(); retry() }
    else if isHashMismatchCode(code) { refetchLink(); recomputeHashes(); retryOnce() }
    else if isNameConflictCode(code) { newName = uniquify(newName); retry() }
}

Prevention

When it happens

Trigger: OriginalHash stale because the file was renamed by another client since the link was fetched; newHash computed with the wrong parent hash key; Name already exists in the parent (Proton enforces per-folder name-hash uniqueness); access token rejected at the API layer.

Common situations: Two clients renaming the same file concurrently; rename after the mount's link cache went stale; keyring/address-key problems producing a wrong name hash; shared-folder permission edges.

Related errors


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