{"record":{"id":"619c7b90ff67ba74","repo":"fish2018/pansou","slug":"error-619c7b","errorCode":null,"errorMessage":"验证数据无效","messagePattern":"验证数据无效","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/gying/gying.go","lineNumber":1777,"sourceCode":"\t\ty.Mod(y, modulus)\n\t}\n\telapsed := time.Since(start)\n\n\tif DebugLog {\n\t\tfmt.Printf(\"[Gying] PoW Challenge计算完成: id=%s t=%d cost=%s\\n\",\n\t\t\tchallenge.ID, challenge.T, elapsed.Round(time.Millisecond))\n\t}\n\n\tif minSolveTime := 3 * time.Second; elapsed < minSolveTime {\n\t\ttime.Sleep(minSolveTime - elapsed)\n\t}\n\n\treturn y.Text(16), nil\n}\n\nfunc (p *GyingPlugin) solveLegacyHashChallenge(scraper *cloudscraper.Scraper, requestURL string, challenge *ChallengePageData) error {\n\tif challenge.ID == \"\" || challenge.Salt == \"\" || challenge.Diff <= 0 || len(challenge.Challenge) == 0 {\n\t\treturn fmt.Errorf(\"验证数据无效\")\n\t}\n\n\tif DebugLog {\n\t\tfmt.Printf(\"[Gying] Challenge命中: url=%s id=%s diff=%d targets=%d\\n\",\n\t\t\trequestURL, challenge.ID, challenge.Diff, len(challenge.Challenge))\n\t}\n\n\tremaining := make(map[string][]int, len(challenge.Challenge))\n\tnonces := make([]int, len(challenge.Challenge))\n\tfor idx, target := range challenge.Challenge {\n\t\thash := strings.ToLower(target)\n\t\tremaining[hash] = append(remaining[hash], idx)\n\t}\n\n\tworkerCount := runtime.GOMAXPROCS(0)\n\tif workerCount < 1 {\n\t\tworkerCount = 1\n\t}","sourceCodeStart":1759,"sourceCodeEnd":1795,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/gying/gying.go#L1759-L1795","documentation":"solveLegacyHashChallenge validates the legacy hash-cash style challenge before brute-forcing SHA-256 nonces: it needs an ID, a salt, a positive Diff (nonce upper bound), and at least one target hash. This error is returned when any of those is missing or invalid, meaning the challenge page data does not match the expected legacy format.","triggerScenarios":"The solver is dispatched to solveLegacyHashChallenge with a ChallengePageData where ID==\"\", Salt==\"\", Diff<=0, or Challenge (target hash list) is empty.","commonSituations":"The site migrated from the legacy hash challenge to the PoW scheme but the dispatcher still routes to the legacy solver; JSON field renaming upstream leaves Salt/Diff/Challenge at zero values; an empty or malformed challenge response was parsed without a hard failure.","solutions":["Dump the raw challenge response and the populated ChallengePageData to see which field is missing","Re-fetch a fresh challenge; transient empty responses are common behind proxies","If the site now serves PoW challenges, route to solvePowChallenge instead of the legacy solver","Update ChallengePageData JSON tags to match the current challenge schema"],"exampleFix":"// before\nif challenge.ID == \"\" || challenge.Salt == \"\" || challenge.Diff <= 0 || len(challenge.Challenge) == 0 {\n    return fmt.Errorf(\"验证数据无效\")\n}\n// after (log which field failed)\nif challenge.ID == \"\" || challenge.Salt == \"\" || challenge.Diff <= 0 || len(challenge.Challenge) == 0 {\n    return fmt.Errorf(\"验证数据无效: id=%q salt=%q diff=%d targets=%d\",\n        challenge.ID, challenge.Salt, challenge.Diff, len(challenge.Challenge))\n}","handlingStrategy":"validation","validationCode":"func validLegacyChallenge(c *ChallengePageData) bool {\n    return c.ID != \"\" && c.Salt != \"\" && c.Diff > 0 && len(c.Challenge) > 0\n}\nif !validLegacyChallenge(ch) { /* route to PoW solver or re-fetch */ }","typeGuard":"func isLegacyHashChallenge(c *ChallengePageData) bool {\n    return c.ID != \"\" && c.Salt != \"\" && c.Diff > 0 && len(c.Challenge) > 0\n}","tryCatchPattern":"if err := p.solveLegacyHashChallenge(scraper, requestURL, challenge); err != nil {\n    if err.Error() == \"验证数据无效\" {\n        return p.solvePowChallenge(scraper, requestURL, challenge) // fallback scheme\n    }\n    return err\n}","preventionTips":["Detect which challenge scheme the server issued before dispatching to a solver","Log raw challenge responses so missing Salt/Diff/Challenge is visible immediately","Re-fetch the challenge page rather than solving a partially-populated struct"],"tags":["challenge","hashcash","validation","anti-bot"],"backgroundTag":"empty-required-field","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}