AlistGo/alist · error

resolution is required

Error message

resolution is required

What it means

Returned by the Thunder captcha-token flow (drivers/thunder/util.go:161) when the verification API responds successfully (no error struct, no verify Url) but resp.CaptchaToken is an empty string. The contract expected a token; an empty one means the response shape changed or the request was silently rejected.

Source

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

		return nil, err
	}
	return d.client.Transcode.DownloadOriginal(ctx, fileID)
}

func otherTranscodeDownloadM3U8(d *Open123, ctx context.Context, args model.OtherArgs) (interface{}, error) {
	var req struct {
		FileID     int64  `json:"file_id"`
		Resolution string `json:"resolution"`
	}
	if err := decodeOtherArgs(args.Data, &req); err != nil {
		return nil, err
	}
	fileID, err := resolveFileID(args, req.FileID)
	if err != nil {
		return nil, err
	}
	if req.Resolution == "" {
		return nil, errors.New("resolution is required")
	}
	return d.client.Transcode.DownloadM3U8(ctx, fileID, req.Resolution)
}

func otherTranscodeDownloadTS(d *Open123, ctx context.Context, args model.OtherArgs) (interface{}, error) {
	var req struct {
		FileID     int64  `json:"file_id"`
		Resolution string `json:"resolution"`
		TsName     string `json:"ts_name"`
	}
	if err := decodeOtherArgs(args.Data, &req); err != nil {
		return nil, err
	}
	fileID, err := resolveFileID(args, req.FileID)
	if err != nil {
		return nil, err
	}
	if req.Resolution == "" || req.TsName == "" {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Update the driver/tool to the latest version — this typically follows an upstream response-format change.
  2. Re-trigger the full verification flow from scratch (fresh request, not a replay) to obtain a new response with a token.
  3. Log the raw response body of the verify call to see whether the token moved to a renamed field, and adjust parsing if you maintain a fork.
  4. Ensure the request includes the same device-id/user-agent pair used at login, otherwise the server may return empty tokens.

Example fix

// before
type CaptchaResp struct {
	CaptchaToken string `json:"captcha_token"`
}

// after: tolerate renamed field
type CaptchaResp struct {
	CaptchaToken string `json:"captcha_token"`
	Token        string `json:"token"` // newer payloads
}
// ...
if resp.CaptchaToken == "" {
	resp.CaptchaToken = resp.Token
}
Defensive patterns

Strategy: retry

Validate before calling

// ensure consistent device identity is sent with the captcha request
req.SetHeaders(map[string]string{
	"User-Agent":  deviceUA, // same UA used at login
	"X-Device-Id": deviceID,
})

Type guard

func isEmptyCaptchaTokenErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "empty captchaToken")
}

Try / catch

if err := c.refreshCaptchaToken(ctx); isEmptyCaptchaTokenErr(err) {
	// re-run the full verify flow once (fresh nonce, same device identity); if it repeats, update driver
}

Prevention

When it happens

Trigger: XunLei changing the verify endpoint response format (token moved to another field); sending stale or incorrect verification parameters so the server returns an empty token instead of an error; intermediate proxies stripping response fields; race where the token was already consumed.

Common situations: After Thunder/XunLei API revisions without a driver update; cookie/session partially valid; replaying the captcha request with an expired nonce; CDN interference.

Related errors


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