babalae/better-genshin-impact · error · InvalidOperationException

天赋点击位置索引越界。

Error message

天赋点击位置索引越界。

What it means

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.

Source

Thrown at BetterGenshinImpact/GameTask/CharacterDevelopment/CharacterDevelopmentTask.cs:789

        using var capture = CaptureToRectArea();
        if (!TryFindTalentPoints(capture, out var points))
        {
            return Task.FromResult(StateHandlerResult.Retry);
        }

        _talentPoints = points;
        _talentIndex = 0;
        _readTalentTypes.Clear();
        _workflowState = CharacterDevelopmentState.OpenTalent;
        return Task.FromResult(StateHandlerResult.Success);
    }

    [StateHandler(CharacterDevelopmentState.OpenTalent, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 5000)]
    private Task<StateHandlerResult> HandleOpenTalent(BvPage page)
    {
        if (_talentIndex < 0 || _talentIndex >= _talentPoints.Count)
        {
            throw new InvalidOperationException("天赋点击位置索引越界。");
        }

        using var capture = CaptureToRectArea();
        var point = _talentPoints[_talentIndex];
        capture.ClickTo(point.X, point.Y);
        _workflowState = CharacterDevelopmentState.ReadTalent;
        return Task.FromResult(StateHandlerResult.Success);
    }

    [StateHandler(CharacterDevelopmentState.ReadTalent, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 5000)]
    private async Task<StateHandlerResult> HandleReadTalent(BvPage page)
    {
        var (type, level, hasBonus) = await ReadTalentDetailWithRetry();

        if (!_readTalentTypes.Add(type))
        {
            return StateHandlerResult.Retry;
        }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Ensure `_talentIndex` is only incremented in `ReadTalent` and reset to 0 whenever `_talentPoints` is rebuilt.
  2. Treat this throw as an internal invariant violation — log state and fix the loop, do not paper over it.
  3. Avoid reentering `OpenTalent` without first rebuilding `_talentPoints`.

Example fix

// before
if (_talentIndex < 0 || _talentIndex >= _talentPoints.Count)
    throw new InvalidOperationException("天赋点击位置索引越界。");

// after: keep the guard; fix the upstream loop that let the index run past Count
Defensive patterns

Strategy: validation

Validate before calling

// Invariant: _talentIndex in [0, _talentPoints.Count). Validate before click:
if (_talentIndex < 0 || _talentIndex >= _talentPoints.Count) return StateHandlerResult.Retry;

Prevention

When it happens

Trigger: `_talentIndex` advanced past `_talentPoints.Count - 1` without `ReadTalent` resetting the flow; `_talentPoints` cleared/replaced between `OpenTalent` calls; concurrent reentry into the talent handlers.

Common situations: A logic bug in the `ReadTalent`→`OpenTalent` loop; an exception mid-loop leaving the index ahead; reentrant state handling.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/7686e950a9edf19c. Report an issue: GitHub.