AlistGo/alist · error
failed to decode rename response: %w
Error message
failed to decode rename response: %w
What it means
The rename response body (on a 200) could not be JSON-decoded into RenameResponse. Proton normally returns {Code, Response...} JSON, so a decode failure means the body was not Proton JSON — typically an HTML error page from an intercepting proxy, Cloudflare, or a captive portal, or an empty/truncated body.
Source
Thrown at drivers/proton_drive/util.go:662
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("Authorization", "Bearer "+d.credentials.AccessToken)
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)View on GitHub (pinned to 843d9dc814)
Solutions
- Capture the raw body (tee it) before decoding to see what was actually returned
- Bypass TLS-inspecting proxies for the Proton API host
- Retry on truncation — it is usually transient
- If HTML is consistently returned, the endpoint is being blocked; fix the network path
Example fix
// before
if err := json.NewDecoder(resp.Body).Decode(&renameResp); err != nil {
// after
body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
if err := json.Unmarshal(body, &renameResp); err != nil {
return fmt.Errorf("failed to decode rename response (%q): %w", truncate(body, 200), err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// sanity check before decode is not possible remotely; guard by checking content type
if ct := resp.Header.Get("Content-Type"); ct != "" && !strings.Contains(ct, "json") {
return fmt.Errorf("unexpected content-type %s from rename endpoint", ct)
} Try / catch
if err := d.Rename(ctx, src, newName); err != nil {
var syn *json.SyntaxError
if errors.As(err, &syn) {
// non-JSON body: proxy/middlebox interference — check network path, then retry
}
} Prevention
- Bypass TLS-inspecting proxies for the Proton API host
- Log raw bodies on decode failures in your fork of the driver
When it happens
Trigger: TLS-intercepting middlebox answering 200 with HTML; connection closed early truncating the JSON; Content-Encoding mismatch; unexpected empty body on some gateway errors.
Common situations: Corporate proxies and antivirus TLS inspection; flaky mobile links where the body is cut off; CDN edge nodes serving a soft-block page that still returns 200.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to marshal rename request: %w
- failed to execute rename request: %w
- failed to marshal move request: %w
- failed to execute move request: %w
- failed to decode move response: %w
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/78454af916f618ff.
Report an issue: GitHub.