{"record":{"id":"7686e950a9edf19c","repo":"babalae/better-genshin-impact","slug":"error-7686e9","errorCode":null,"errorMessage":"天赋点击位置索引越界。","messagePattern":"天赋点击位置索引越界。","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs","lineNumber":789,"sourceCode":"        using var capture = CaptureToRectArea();\n        if (!TryFindTalentPoints(capture, out var points))\n        {\n            return Task.FromResult(StateHandlerResult.Retry);\n        }\n\n        _talentPoints = points;\n        _talentIndex = 0;\n        _readTalentTypes.Clear();\n        _workflowState = CharacterDevelopmentState.OpenTalent;\n        return Task.FromResult(StateHandlerResult.Success);\n    }\n\n    [StateHandler(CharacterDevelopmentState.OpenTalent, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 5000)]\n    private Task<StateHandlerResult> HandleOpenTalent(BvPage page)\n    {\n        if (_talentIndex < 0 || _talentIndex >= _talentPoints.Count)\n        {\n            throw new InvalidOperationException(\"天赋点击位置索引越界。\");\n        }\n\n        using var capture = CaptureToRectArea();\n        var point = _talentPoints[_talentIndex];\n        capture.ClickTo(point.X, point.Y);\n        _workflowState = CharacterDevelopmentState.ReadTalent;\n        return Task.FromResult(StateHandlerResult.Success);\n    }\n\n    [StateHandler(CharacterDevelopmentState.ReadTalent, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 5000)]\n    private async Task<StateHandlerResult> HandleReadTalent(BvPage page)\n    {\n        var (type, level, hasBonus) = await ReadTalentDetailWithRetry();\n\n        if (!_readTalentTypes.Add(type))\n        {\n            return StateHandlerResult.Retry;\n        }","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs#L771-L807","documentation":"Defensive bounds check in the `OpenTalent` handler: `_talentIndex` must be a valid index into `_talentPoints` before clicking. `TryFindTalentPoints` guarantees exactly 3 points and resets the index to 0, so a valid index is an invariant of the talent sub-flow; reaching this throw indicates the index was corrupted or the points list changed unexpectedly.","triggerScenarios":"`_talentIndex` advanced past `_talentPoints.Count - 1` without `ReadTalent` resetting the flow; `_talentPoints` cleared/replaced between `OpenTalent` calls; concurrent reentry into the talent handlers.","commonSituations":"A logic bug in the `ReadTalent`→`OpenTalent` loop; an exception mid-loop leaving the index ahead; reentrant state handling.","solutions":["Ensure `_talentIndex` is only incremented in `ReadTalent` and reset to 0 whenever `_talentPoints` is rebuilt.","Treat this throw as an internal invariant violation — log state and fix the loop, do not paper over it.","Avoid reentering `OpenTalent` without first rebuilding `_talentPoints`."],"exampleFix":"// before\nif (_talentIndex < 0 || _talentIndex >= _talentPoints.Count)\n    throw new InvalidOperationException(\"天赋点击位置索引越界。\");\n\n// after: keep the guard; fix the upstream loop that let the index run past Count","handlingStrategy":"validation","validationCode":"// Invariant: _talentIndex in [0, _talentPoints.Count). Validate before click:\nif (_talentIndex < 0 || _talentIndex >= _talentPoints.Count) return StateHandlerResult.Retry;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only increment _talentIndex in ReadTalent; reset to 0 when rebuilding _talentPoints.","Treat this throw as an invariant violation — fix the loop, don't suppress it.","Avoid reentering OpenTalent without rebuilding _talentPoints."],"tags":["state-machine","bounds-check","invariant","talent","character-development"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}