fish2018/pansou · error

[ ] 人机验证未通过

Error message

[%s] 人机验证未通过: %w

What it means

This error is returned by MiosouPlugin.ensureGate after 3 attempts of completeAnubisChallenge all fail; the last attempt's error is wrapped. ensureGate is invoked by searchImpl before searching (and again when a gate response is detected), so this error means the Anubis proof-of-work anti-bot challenge could not be solved or submitted.

Solutions

  1. Read the wrapped lastErr to see which stage failed (request, parse, solve, or submit)
  2. Increase gateTimeout if solveAnubisChallenge runs out of time due to high difficulty
  3. Update parseAnubisChallenge and the pass request against the site's current Anubis version
  4. Test from a different IP/network — flagged IPs get endless challenges

Example fix

// before
ctx, cancel := context.WithTimeout(context.Background(), gateTimeout)
err := p.completeAnubisChallenge(ctx)
// after (only if timeouts are the wrapped cause)
gateTimeout = 60 * time.Second // raised from previous value
ctx, cancel := context.WithTimeout(context.Background(), gateTimeout)
Defensive patterns

Strategy: retry

Validate before calling

// Go: check challenge fetchability before full ensureGate
resp, err := http.Get(baseURL + "/")
if err != nil || resp.StatusCode != http.StatusOK {
    // cannot even reach challenge page; skip and retry later
}

Type guard

func isGateFailure(err error) bool {
    return err != nil && strings.Contains(err.Error(), "人机验证未通过")
}

Try / catch

if err := p.ensureGate(); err != nil {
    var to net.Error
    if errors.As(err, &to) && to.Timeout() {
        gateTimeout *= 2 // difficulty may have increased; give PoW more time
    }
    return nil, fmt.Errorf("gate setup failed, will retry later: %w", err)
}

Prevention

When it happens

Trigger: ensureGate loops 3 times calling completeAnubisChallenge(ctx) with gateTimeout context; every attempt returns an error (challenge request failed, page fetch failed, challenge not found with non-200, PoW solve failed, or pass submission rejected), producing "人机验证未通过: <lastErr>".

Common situations: Anubis difficulty raised so PoW cannot finish within gateTimeout; site updated the challenge page markup so parseAnubisChallenge returns found=false with non-200; pass-endpoint response rejected; the host is on a blocklist so every challenge is invalidated.

Related errors


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

Appendix: source

Thrown at plugin/miosou/miosou.go:151

func (p *MiosouPlugin) ensureGate() error {
	p.gateMu.Lock()
	defer p.gateMu.Unlock()
	if p.gateReady {
		return nil
	}

	var lastErr error
	for attempt := 0; attempt < 3; attempt++ {
		ctx, cancel := context.WithTimeout(context.Background(), gateTimeout)
		err := p.completeAnubisChallenge(ctx)
		cancel()
		if err == nil {
			p.gateReady = true
			return nil
		}
		lastErr = err
	}
	return fmt.Errorf("[%s] 人机验证未通过: %w", p.Name(), lastErr)
}

func (p *MiosouPlugin) completeAnubisChallenge(ctx context.Context) error {
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+"/", nil)
	if err != nil {
		return fmt.Errorf("创建 Anubis 验证请求失败: %w", err)
	}
	setPageHeaders(req)
	resp, err := p.client.Do(req)
	if err != nil {
		return fmt.Errorf("获取 Anubis 验证题目失败: %w", err)
	}
	body, readErr := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
	resp.Body.Close()
	if readErr != nil {
		return fmt.Errorf("读取 Anubis 验证题目失败: %w", readErr)
	}
	challenge, found, err := parseAnubisChallenge(body)

View on GitHub (pinned to beaa561337)