AlistGo/alist · error

url is required

Error message

url is required

What it means

Wrapped error from XunLeiCommon.DeleteOfflineTasks (drivers/thunder/driver.go:659) when the DELETE to TASK_API_URL with task_ids and delete_files fails. The %w keeps the underlying cause; the offending task IDs are included for diagnosis.

Source

Thrown at drivers/123_open/other.go:597

	if err != nil {
		return nil, err
	}
	return okResult{Success: done}, nil
}

// ---------------------------------------------------------------- offline download

// offlineDownloadArgs is shared by the cloud disk and the image hosting task.
type offlineDownloadArgs struct {
	URL         string `json:"url"`
	FileName    string `json:"file_name"`
	DirID       int64  `json:"dir_id"`
	CallBackURL string `json:"call_back_url"`
}

func (a offlineDownloadArgs) toRequest(args model.OtherArgs) (*pan123.OfflineDownloadRequest, error) {
	if a.URL == "" {
		return nil, errors.New("url is required")
	}
	dirID := a.DirID
	if dirID == 0 && args.Obj != nil && args.Obj.IsDir() {
		parsed, err := parseFileID(args.Obj.GetID())
		if err != nil {
			return nil, err
		}
		dirID = parsed
	}
	return &pan123.OfflineDownloadRequest{
		URL:         a.URL,
		FileName:    a.FileName,
		DirID:       dirID,
		CallBackURL: a.CallBackURL,
	}, nil
}

type taskIDArgs struct {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Retry once after refreshing the session if the wrapped cause is auth/captcha related.
  2. Filter task IDs against a fresh GetOfflineTasks listing before deleting to drop already-removed IDs.
  3. For very large batches, chunk the deletion to avoid URL/param length limits and rate limiting.
  4. If delete_files=true consistently fails, retry with delete_files=false to at least remove the task entries, then clean files separately.

Example fix

// before
err := xc.DeleteOfflineTasks(ctx, ids, true)

// after: drop stale ids and retry once on auth errors
live := filterExistingTasks(ctx, xc, ids)
err := xc.DeleteOfflineTasks(ctx, live, true)
if err != nil && isAuthOrCaptchaErr(errors.Unwrap(err)) {
	_ = xc.refreshSession(ctx)
	err = xc.DeleteOfflineTasks(ctx, live, true)
}
Defensive patterns

Strategy: validation

Validate before calling

// intersect requested IDs with live tasks before deleting
live := map[string]bool{}
if tasks, err := xc.GetOfflineTasks(ctx, token); err == nil {
	for _, t := range tasks {
		live[t.ID] = true
	}
}
valid := ids[:0]
for _, id := range ids {
	if live[id] {
		valid = append(valid, id)
	}
}

Type guard

func isDeleteTasksErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "failed to delete tasks")
}

Try / catch

if err := xc.DeleteOfflineTasks(ctx, valid, deleteFiles); isDeleteTasksErr(err) {
	if isAuthOrCaptchaErr(errors.Unwrap(err)) {
		_ = xc.refreshSession(ctx)
		err = xc.DeleteOfflineTasks(ctx, valid, deleteFiles)
	}
}

Prevention

When it happens

Trigger: Deleting offline tasks when the session/captcha token expired; passing task IDs that were already deleted or belong to another device; delete_files=true while files are locked or being transferred; transient network failure.

Common situations: UI double-submits a delete so the second call fails (already-gone IDs); batch deletion of many tasks hitting rate limits; token rotation between listing and deleting.

Related errors


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