AlistGo/alist · error
failed to parse task id: %w
Error message
failed to parse task id: %w
What it means
After a 202 response to a folder copy, the SJTU driver parses the body as a task-init response ({task_id}). This error fires when JSON unmarshal fails OR the parsed TaskId is 0. Note the bug: when TaskId==0 but unmarshal succeeded, err is nil, so the message renders '%!w(<nil>)' and the real cause is the zero/missing task_id field.
Source
Thrown at drivers/sjtu_netdisk/driver.go:549
return &model.Object{
Name: srcObj.GetName(),
Size: srcObj.GetSize(),
IsFolder: true,
Modified: srcObj.ModTime(),
Ctime: time.Now(),
Path: targetPath,
}, nil
}
// 202 Accepted:polling task status
if resp.StatusCode() != http.StatusAccepted {
return nil, fmt.Errorf("unexpected copy folder response: status=%d", resp.StatusCode())
}
var taskResp TaskInitResp
if err := json.Unmarshal(resp.Body(), &taskResp); err != nil || taskResp.TaskId == 0 {
return nil, fmt.Errorf("failed to parse task id: %w", err)
}
taskURL := fmt.Sprintf("%s/task/%s/%s/%d", API_URL, d.libraryId, d.spaceId, taskResp.TaskId)
actualName := srcObj.GetName()
taskDone := false
for i := 0; i < 30 && !taskDone; i++ {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(1 * time.Second):
}
var taskStatus []TaskStatusItem
_, pollErr := d.newClient().R().
SetContext(ctx).
SetQueryParam("access_token", d.accessToken).
SetResult(&taskStatus).View on GitHub (pinned to 843d9dc814)
Solutions
- Retry the copy — transient 202-with-bad-body responses occur under server load
- Inspect the raw response body (log it) to see what the server actually returned
- If a proxy is involved, bypass it or fix its response handling
- If the field name changed upstream, update TaskInitResp's json tag in the driver
- Fix the driver to distinguish unmarshal failure from zero task id and include the body in the error
Example fix
// before
if err := json.Unmarshal(resp.Body(), &taskResp); err != nil || taskResp.TaskId == 0 {
return nil, fmt.Errorf("failed to parse task id: %w", err)
}
// after
if err := json.Unmarshal(resp.Body(), &taskResp); err != nil {
return nil, fmt.Errorf("failed to parse task id: %w, body: %s", err, resp.String())
}
if taskResp.TaskId == 0 {
return nil, fmt.Errorf("task id missing in response body: %s", resp.String())
} Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.Contains(err.Error(), "failed to parse task id") {
// body was empty/reshaped or task_id was 0; a fresh copy gets a new task
return retryFolderCopyOnce()
} Prevention
- Note '%!w(<nil>)' in the message means task_id was 0, not a JSON error — inspect the body
- Retry once; transient malformed 202 bodies occur under load
- Keep proxies from rewriting 202 response bodies
When it happens
Trigger: Server returns 202 with an empty or differently-shaped body (e.g. an error page from a proxy), or a JSON without a usable task_id field; also any body where task_id is absent/0.
Common situations: Reverse proxy intercepting the 202 and rewriting the body; API version change renaming the task id field; server acknowledging but failing to schedule the task.
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 parse response: %v
- unexpected copy folder response: status=%d
- Too many parts, please increase part size
- error:%v
- invalid json
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/e83cad33b94c6cab.
Report an issue: GitHub.