AlistGo/alist · error
get upload token failed: empty task id
Error message
get upload token failed: empty task id
What it means
After POST to obtain an upload task the server replied with a success-ish message, but out.Data.TaskID is empty. The upload token exchange (fileSize included in the res map) is useless without a task id — the subsequent OSS-style credential fields (AccessKeyID/SessionToken/EndPoint fallbacks that follow) all belong to a task. The guard aborts before handing back unusable credentials.
Source
Thrown at drivers/guangyapan/driver.go:900
func (d *GuangYaPan) getUploadToken(ctx context.Context, parentID, name string, size int64) (*uploadTokenData, int, error) {
var out uploadTokenResp
err := d.postAPI(ctx, "/nd.bizuserres.s/v1/get_res_center_token", map[string]any{
"capacity": 2,
"name": name,
"parentId": parentID,
"res": map[string]any{
"fileSize": size,
},
}, &out)
if err != nil {
return nil, 0, err
}
msg := strings.TrimSpace(out.Msg)
if msg != "" && !strings.EqualFold(msg, "success") {
return nil, out.Code, fmt.Errorf("get upload token failed: %s", msg)
}
if out.Data.TaskID == "" {
return nil, out.Code, errors.New("get upload token failed: empty task id")
}
if out.Data.AccessKeyID == "" {
out.Data.AccessKeyID = out.Data.Creds.AccessKeyID
}
if out.Data.SecretAccessKey == "" {
out.Data.SecretAccessKey = out.Data.Creds.SecretAccessKey
}
if out.Data.SessionToken == "" {
out.Data.SessionToken = out.Data.Creds.SessionToken
}
if strings.TrimSpace(out.Data.EndPoint) == "" {
out.Data.EndPoint = strings.TrimSpace(out.Data.FullEndPoint)
}
if strings.TrimSpace(out.Data.EndPoint) != "" && !strings.HasPrefix(out.Data.EndPoint, "http://") && !strings.HasPrefix(out.Data.EndPoint, "https://") {
if strings.TrimSpace(out.Data.FullEndPoint) != "" {
out.Data.EndPoint = strings.TrimSpace(out.Data.FullEndPoint)
} else if strings.TrimSpace(out.Data.BucketName) != "" {
host := strings.TrimSpace(out.Data.EndPoint)View on GitHub (pinned to 843d9dc814)
Solutions
- Log out.Code and the raw response body for the upload-token call to see what the server actually returned
- Reject zero-byte uploads before calling getUploadToken; some backends refuse them with this shape
- Verify the response struct in types.go matches the current API field names (taskId vs task_id casing via json tags)
- Retry once — a transient gateway truncation can produce an empty data object
Defensive patterns
Strategy: validation
Validate before calling
if size <= 0 {
return nil, 0, errors.New("guangyapan upload requires a positive file size")
} Try / catch
token, code, err := d.getUploadToken(ctx, name, size)
if err != nil && strings.Contains(err.Error(), "empty task id") {
// server accepted but created no task: surface size/code for diagnosis
return fmt.Errorf("upload token rejected (size=%d code=%d): %w", size, code, err)
} Prevention
- Reject zero-byte uploads client-side before requesting an upload token
- Pin and log the raw upload-token response in tests to catch API schema drift early
When it happens
Trigger: Upload-token endpoint returns msg="success" (or empty) yet omits data.taskId. Seen with fileSize==0 uploads the backend silently rejects, response envelope drift (task id nested elsewhere), or a truncated success response from a rate-limited gateway.
Common situations: Attempting to upload a 0-byte file; provider API version bump renaming taskId; account out of quota so backend returns success-shaped body without creating a task.
Related errors
- file is nil
- validate token failed: empty user sub
- create offline task failed: empty task id
- login failed: provide a valid access_token, or refresh_token
- empty download url
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/c7ddc3151bb6e72d.
Report an issue: GitHub.