{"record":{"id":"d31ebdd1923d4aa3","repo":"AlistGo/alist","slug":"resolution-is-required","errorCode":null,"errorMessage":"resolution is required","messagePattern":"resolution is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/123_open/other.go","lineNumber":834,"sourceCode":"\t\treturn nil, err\n\t}\n\treturn d.client.Transcode.DownloadOriginal(ctx, fileID)\n}\n\nfunc otherTranscodeDownloadM3U8(d *Open123, ctx context.Context, args model.OtherArgs) (interface{}, error) {\n\tvar req struct {\n\t\tFileID     int64  `json:\"file_id\"`\n\t\tResolution string `json:\"resolution\"`\n\t}\n\tif err := decodeOtherArgs(args.Data, &req); err != nil {\n\t\treturn nil, err\n\t}\n\tfileID, err := resolveFileID(args, req.FileID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif req.Resolution == \"\" {\n\t\treturn nil, errors.New(\"resolution is required\")\n\t}\n\treturn d.client.Transcode.DownloadM3U8(ctx, fileID, req.Resolution)\n}\n\nfunc otherTranscodeDownloadTS(d *Open123, ctx context.Context, args model.OtherArgs) (interface{}, error) {\n\tvar req struct {\n\t\tFileID     int64  `json:\"file_id\"`\n\t\tResolution string `json:\"resolution\"`\n\t\tTsName     string `json:\"ts_name\"`\n\t}\n\tif err := decodeOtherArgs(args.Data, &req); err != nil {\n\t\treturn nil, err\n\t}\n\tfileID, err := resolveFileID(args, req.FileID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif req.Resolution == \"\" || req.TsName == \"\" {","sourceCodeStart":816,"sourceCodeEnd":852,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/123_open/other.go#L816-L852","documentation":"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.","triggerScenarios":"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.","commonSituations":"After Thunder/XunLei API revisions without a driver update; cookie/session partially valid; replaying the captcha request with an expired nonce; CDN interference.","solutions":["Update the driver/tool to the latest version — this typically follows an upstream response-format change.","Re-trigger the full verification flow from scratch (fresh request, not a replay) to obtain a new response with a token.","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.","Ensure the request includes the same device-id/user-agent pair used at login, otherwise the server may return empty tokens."],"exampleFix":"// before\ntype CaptchaResp struct {\n\tCaptchaToken string `json:\"captcha_token\"`\n}\n\n// after: tolerate renamed field\ntype CaptchaResp struct {\n\tCaptchaToken string `json:\"captcha_token\"`\n\tToken        string `json:\"token\"` // newer payloads\n}\n// ...\nif resp.CaptchaToken == \"\" {\n\tresp.CaptchaToken = resp.Token\n}","handlingStrategy":"retry","validationCode":"// ensure consistent device identity is sent with the captcha request\nreq.SetHeaders(map[string]string{\n\t\"User-Agent\":  deviceUA, // same UA used at login\n\t\"X-Device-Id\": deviceID,\n})","typeGuard":"func isEmptyCaptchaTokenErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"empty captchaToken\")\n}","tryCatchPattern":"if err := c.refreshCaptchaToken(ctx); isEmptyCaptchaTokenErr(err) {\n\t// re-run the full verify flow once (fresh nonce, same device identity); if it repeats, update driver\n}","preventionTips":["Always send the same device-id/UA pair used at login.","Never replay captcha requests with stale nonces.","Update the driver when XunLei revises the verify response schema."],"tags":["thunder","xunlei","captcha-token","upstream-drift"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}