fish2018/pansou · error

未找到ptsigx

Error message

未找到ptsigx

What it means

extractLoginInfo (plugin/qqpd/qqpd.go:1857) matched the ptuiCB callback and URL, but the regex `ptsigx=([A-Za-z0-9]+)` found no ptsigx parameter in the extracted URL, so it returns '未找到ptsigx'. ptsigx is the signing token required for the follow-up check_sig cookie exchange, so login cannot proceed without it.

Solutions

  1. Log the extracted URL and inspect which query parameters are actually present
  2. Update the ptsigx regex if QQ changed the parameter name or charset (e.g. allowing '_' or '%')
  3. Handle alternate URL forms (URL-decode first in case the sign param is percent-encoded)
  4. Regenerate the QR code and retry the login flow

Example fix

// before
ptsigxRe := regexp.MustCompile(`ptsigx=([A-Za-z0-9]+)`)
// after
ptsigxRe := regexp.MustCompile(`ptsigx=([^&']+)`)
Defensive patterns

Strategy: validation

Validate before calling

// verify expected query params before extraction
u, err := url.Parse(extractedURL)
if err != nil {
    return fmt.Errorf("bad login url: %w", err)
}
if u.Query().Get("ptsigx") == "" {
    return errors.New("login url missing ptsigx")
}

Type guard

func hasPtsigx(loginURL string) bool {
    u, err := url.Parse(loginURL)
    return err == nil && u.Query().Get("ptsigx") != ""
}

Try / catch

ptsigx, uin, err := p.extractLoginInfo(bodyStr)
if err != nil {
    if err.Error() == "未找到ptsigx" {
        // login URL shape changed or sign missing; restart QR flow with diagnostics
        return nil, fmt.Errorf("login url lacked ptsigx, refresh QR: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: checkQRLoginStatus -> extractLoginInfo: the ptuiCB URL exists but lacks a ptsigx query parameter — QQ returned a redirect URL variant without the sign token.

Common situations: QQ A/B-testing a new login URL shape, the URL being a jump/verify URL (e.g. needing an extra verification step), or a truncated/malformed callback URL.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/9edb8659ba08e6fd. Report an issue: GitHub.

Appendix: source

Thrown at plugin/qqpd/qqpd.go:1857

	start := strings.Index(responseText, "ptuiCB(")
	if start == -1 {
		return "", "", fmt.Errorf("未找到ptuiCB")
	}

	// 简单解析,提取URL部分
	re := regexp.MustCompile(`ptuiCB\('0','0','([^']+)'`)
	matches := re.FindStringSubmatch(responseText)
	if len(matches) < 2 {
		return "", "", fmt.Errorf("无法解析响应")
	}

	url := matches[1]

	// 提取ptsigx
	ptsigxRe := regexp.MustCompile(`ptsigx=([A-Za-z0-9]+)`)
	ptsigxMatches := ptsigxRe.FindStringSubmatch(url)
	if len(ptsigxMatches) < 2 {
		return "", "", fmt.Errorf("未找到ptsigx")
	}
	ptsigx := ptsigxMatches[1]

	// 提取uin
	uinRe := regexp.MustCompile(`uin=(\d+)`)
	uinMatches := uinRe.FindStringSubmatch(url)
	if len(uinMatches) < 2 {
		return "", "", fmt.Errorf("未找到uin")
	}
	uin := uinMatches[1]

	return ptsigx, uin, nil
}

// fetchFullCookie 获取完整Cookie
func (p *QQPDPlugin) fetchFullCookie(uin, ptsigx, setCookieHeader string) (string, error) {
	checkSigURL := fmt.Sprintf("https://ptlogin2.pd.qq.com/check_sig?pttype=1&uin=%s&service=ptqrlogin&nodirect=1&ptsigx=%s&s_url=https%%3A%%2F%%2Fpd.qq.com%%2Fexplore&f_url=&ptlang=2052&ptredirect=101&aid=1600001587&daid=823&j_later=0&low_login_hour=0&regmaster=0&pt_login_type=3&pt_aid=0&pt_aaid=16&pt_light=0&pt_3rd_aid=0", uin, ptsigx)

View on GitHub (pinned to beaa561337)