{"record":{"id":"45229c94c8e825ad","repo":"fish2018/pansou","slug":"s-45229c","errorCode":null,"errorMessage":"[%s] 计算访问挑战失败","messagePattern":"\\[(.+?)\\] 计算访问挑战失败","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/nsgame/nsgame.go","lineNumber":326,"sourceCode":"func (p *NSGameAsyncPlugin) ensureSession(client *http.Client) error {\n\tstatus, err := p.postSession(client, \"/traffic/session/status\", nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif status {\n\t\treturn nil\n\t}\n\tchallengeBody, err := p.postSessionRaw(client, \"/traffic/session/challenge\", nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar challenge nsgameChallengeResponse\n\tif err := json.Unmarshal(challengeBody, &challenge); err != nil || !challenge.Success || challenge.Data.Challenge == \"\" {\n\t\treturn fmt.Errorf(\"[%s] 获取访问挑战失败\", p.Name())\n\t}\n\tnonce := solveChallenge(challenge.Data.Challenge, challenge.Data.DifficultyBits)\n\tif nonce == \"\" {\n\t\treturn fmt.Errorf(\"[%s] 计算访问挑战失败\", p.Name())\n\t}\n\tissueBody, _ := json.Marshal(map[string]string{\"challenge\": challenge.Data.Challenge, \"nonce\": nonce})\n\tif _, err := p.postSessionRaw(client, \"/traffic/session/issue\", issueBody); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (p *NSGameAsyncPlugin) postSession(client *http.Client, path string, body []byte) (bool, error) {\n\tdata, err := p.postSessionRaw(client, path, body)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tvar response nsgameSessionResponse\n\tif err := json.Unmarshal(data, &response); err != nil {\n\t\treturn false, fmt.Errorf(\"[%s] 解析会话响应失败: %w\", p.Name(), err)\n\t}\n\tactive, _ := response.Data.(bool)","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/nsgame/nsgame.go#L308-L344","documentation":"After fetching the challenge, ensureSession calls solveChallenge to compute a proof-of-work nonce; this error means solveChallenge returned an empty string, i.e. no valid nonce was found for the given challenge and difficulty. The PoW was not solved, so the session cannot be issued and the search fails.","triggerScenarios":"solveChallenge exhausts its nonce search space / iteration limit without finding a hash meeting difficultyBits, or it returns \"\" due to an unexpected challenge format (e.g. non-hex challenge string) it cannot hash.","commonSituations":"The site raised difficultyBits so the solver's max-iterations cap is too low; the challenge format changed (longer salt, different hash algorithm) breaking the solver; CPU-constrained host times out before solving.","solutions":["Inspect solveChallenge's iteration cap and raise it, or make it difficulty-aware, when difficultyBits increases","Log challenge and difficultyBits alongside the failure to reproduce the PoW failure","Verify the hash algorithm/prefix expected by the site hasn't changed and update solveChallenge","Retry the whole ensureSession — a fresh challenge may be easier or valid for the solver","Run the solver on more parallel goroutines if difficulty is legitimately high"],"exampleFix":"// before\nnonce := solveChallenge(challenge.Data.Challenge, challenge.Data.DifficultyBits)\nif nonce == \"\" {\n    return fmt.Errorf(\"[%s] 计算访问挑战失败\", p.Name())\n}\n// after\nnonce := solveChallenge(challenge.Data.Challenge, challenge.Data.DifficultyBits)\nif nonce == \"\" {\n    return fmt.Errorf(\"[%s] 计算访问挑战失败: difficulty=%d, challenge=%s\", p.Name(), challenge.Data.DifficultyBits, challenge.Data.Challenge)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := plugin.Search(keyword, ext)\nif err != nil && strings.Contains(err.Error(), \"计算访问挑战失败\") {\n    // fresh challenge may be easier: re-run once\n    results, err = plugin.Search(keyword, ext)\n}","preventionTips":["Make the PoW solver difficulty-aware instead of using a fixed iteration cap","Log difficultyBits trends so a site-side difficulty raise is noticed early","Verify the hash algorithm against the site's JS whenever it updates","Allocate CPU headroom so solving completes within the request timeout"],"tags":["proof-of-work","anti-bot","session","go"],"backgroundTag":"unexpected-api-response-shape","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"}