AlistGo/alist · error

refresh token is empty

Error message

refresh token is empty

What it means

Returned by Xunlei (Thunder) browser driver's token refresh when the XLUSER /auth/token call technically succeeded but the response carries no refresh_token. The driver deliberately fails instead of proceeding with a token that cannot be refreshed later, which would silently log the user out on next expiry.

Source

Thrown at drivers/thunder_browser/driver.go:644

}

// RefreshToken 刷新Token
func (xc *XunLeiBrowserCommon) RefreshToken(refreshToken string) (*TokenResp, error) {
	var resp TokenResp
	_, err := xc.Common.Request(XLUSER_API_URL+"/auth/token", http.MethodPost, func(req *resty.Request) {
		req.SetBody(&base.Json{
			"grant_type":    "refresh_token",
			"refresh_token": refreshToken,
			"client_id":     xc.ClientID,
			"client_secret": xc.ClientSecret,
		})
	}, &resp)
	if err != nil {
		return nil, err
	}

	if resp.RefreshToken == "" {
		return nil, errors.New("refresh token is empty")
	}
	return &resp, nil
}

// GetSafeAccessToken 获取 超级保险柜 AccessToken
func (xc *XunLeiBrowserCommon) GetSafeAccessToken(safePassword string) (string, error) {
	var resp TokenResp
	_, err := xc.Request(XLUSER_API_URL+"/password/check", http.MethodPost, func(req *resty.Request) {
		req.SetBody(&base.Json{
			"scene":    "box",
			"password": EncryptPassword(safePassword),
		})
	}, &resp)
	if err != nil {
		return "", err
	}

	if resp.Token == "" {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Remove and re-add the Thunder browser storage in alist so a fresh sign-in flow issues new tokens
  2. Ensure only one active client uses this Xunlei account; sign out other third-party clients
  3. If it recurs rapidly, re-login in the official Xunlei web client first to clear any risk-control state, then re-add the storage
Defensive patterns

Strategy: try-catch

Try / catch

tok, err := xc.RefreshToken(token)
if err != nil {
    if strings.Contains(err.Error(), "refresh token is empty") {
        // hard stop: interactive re-login required; do NOT loop retries
        return nil, fmt.Errorf("xunlei session expired: re-add the storage to trigger a fresh login")
    }
    return nil, err
}

Prevention

When it happens

Trigger: POST to XLUSER_API_URL /auth/token with grant_type=refresh_token where resp.RefreshToken is empty — typically the server rejected the old refresh token but responded 200 with an error payload, or the account was logged in elsewhere invalidating the session.

Common situations: Logging into the same Xunlei account from multiple tools/devices causing token invalidation; Long-idle storage whose refresh token already expired (Xunlei tokens are short-lived); Xunlei server-side policy changes or risk-control blocks on the client_id used by third-party drivers

Related errors


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