hmjz100/LinkSwift · error · Error

错误:<br/>令牌刷新失败,${res?.error_description || res?.error || "未知

Error message

错误:<br/>令牌刷新失败,${res?.error_description || res?.error || "未知错误"}

What it means

Thrown during credential/captcha token refresh when the refresh API responds successfully at the HTTP layer but does NOT return a captcha_token. The code expects res.captcha_token plus expires_in to cache a captcha token; if the response lacks it, it surfaces the server's error_description / error fields, falling back to '未知错误'. It indicates the cloud provider refused the token refresh.

Source

Thrown at (改)网盘直链下载助手.user.js:7716

					const res = await base.post(config.$xunlei.api.getCaptchaToken, {
						client_id: clientId,
						action: "get:/drive/v1/about",
						device_id: deviceId,
						meta: {
							username: "", phone_number: "", email: "",
							package_name: location.host,
							client_version: clientVersion,
							captcha_sign: this._getCaptchaSign(clientId, clientVersion, location.host, deviceId, timestamp.toString()),
							timestamp: timestamp.toString(),
							user_id: userId
						}
					}, { "Content-Type": "application/json" });

					if (res?.captcha_token) {
						cap = { token: res.captcha_token, expires_at: new Date(timestamp + res.expires_in * 1000).toString() };
						base.setStorage(capKey, cap);
					} else {
						throw new Error(`错误:<br/>令牌刷新失败,${res?.error_description || res?.error || "未知错误"}`);
					}
				} else if (!creds || !cap || !clientId || !deviceId) {
					throw new Error(`错误:<br/>请先登录网盘后再获取文件呢~`);
				}

				return { credentials: creds, captcha: cap, device_id: deviceId };
			});
		},
		async getFileUrl(item, index, isRetry = false) {
			if (item.downloadUrl) return { index, downloadUrl: item.downloadUrl };

			// 获取当前内存中的 token
			const token = await this.getToken(false, false).catch(e => {
				if (e instanceof Error) throw e;
				throw new Error(e?.message || e || "[迅雷云盘] 获取令牌失败");
			});

			const res = await base.get(config.$xunlei.api.getLink + item.id, {

View on GitHub (pinned to 417ea5e28a)

Solutions

  1. Log out and log back into the cloud drive in the userscript to regenerate credentials
  2. Read the embedded error_description in the message (e.g. invalid_grant) and act on it — most often re-authentication
  3. Clear the userscript's cached storage keys (credentials, captcha) and retry the refresh
  4. Check system clock accuracy if the error mentions expired/invalid token timestamps
Defensive patterns

Strategy: retry

Validate before calling

const creds = base.getStorage(credsKey);
if (!creds?.refresh_token) { promptLogin(); }

Type guard

function hasCaptcha(res) { return typeof res?.captcha_token === 'string' && res.captcha_token.length > 0; }

Try / catch

try { await refreshCreds(); } catch (e) { if (e.message.includes('令牌刷新失败')) { clearStoredCredentials(); promptLogin(); } else throw e; }

Prevention

When it happens

Trigger: Calling the token-refresh endpoint (POST with JSON body) and receiving a JSON body without captcha_token — e.g. {error: 'invalid_grant'} or {error_description: '...'} — typically when stored credentials (creds) are expired, revoked, or the device/client ID is rejected.

Common situations: User logged out or changed password on the cloud drive, invalidating stored refresh credentials; captcha/anti-bot policy change server-side; clock skew making cached captcha look valid; clientId/deviceId mismatch after clearing browser storage.

Related errors


AI-assisted analysis of hmjz100/LinkSwift@417ea5e28a (2026-09-02). Data as JSON: /api/errors/e2d21398ced17730. Report an issue: GitHub.