babalae/better-genshin-impact · error · InvalidOperationException

无法读取分类 {_currentCategory}。

Error message

无法读取分类 {_currentCategory}。

What it means

The `ReadCategory` handler only implements `Attribute` and `Weapon` (the Talent category is handled by a different state path: `FindTalentEntries`→`OpenTalent`→`ReadTalent`). Reaching `ReadCategory` with `_currentCategory` equal to `Talent` (or `None`) means the category queue/state was set up incorrectly, so it throws rather than silently skip.

Source

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

    {
        PrepareCharacter(_characterIndex + 1);
        _workflowState = CharacterDevelopmentState.OpenCharacterList;
        return Task.FromResult(StateHandlerResult.Success);
    }

    [StateHandler(CharacterDevelopmentState.ReadCategory, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 3000)]
    private async Task<StateHandlerResult> HandleReadCategory(BvPage page)
    {
        switch (_currentCategory)
        {
            case CharacterDevelopmentCategory.Attribute:
                await ReadAttribute();
                break;
            case CharacterDevelopmentCategory.Weapon:
                await ReadWeapon();
                break;
            default:
                throw new InvalidOperationException($"无法读取分类 {_currentCategory}。");
        }

        _workflowState = CharacterDevelopmentState.SwitchCategory;
        return StateHandlerResult.Success;
    }

    [StateHandler(CharacterDevelopmentState.FindTalentEntries, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 3000)]
    private Task<StateHandlerResult> HandleFindTalentEntries(BvPage page)
    {
        using var capture = CaptureToRectArea();
        if (!TryFindTalentPoints(capture, out var points))
        {
            return Task.FromResult(StateHandlerResult.Retry);
        }

        _talentPoints = points;
        _talentIndex = 0;
        _readTalentTypes.Clear();

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify `SwitchCategory` routes `Talent` to `FindTalentEntries`, not `ReadCategory`.
  2. Keep the `ReadCategory` switch and the `SwitchCategory` routing in sync when adding categories.
  3. If Talent reaches here, treat it as a state-machine bug and fix the transition, not the handler.

Example fix

// before: default branch reached for Talent
switch (_currentCategory) {
    case Attribute: await ReadAttribute(); break;
    case Weapon: await ReadWeapon(); break;
    default: throw new InvalidOperationException(...);
}

// after: ensure SwitchCategory sends Talent to FindTalentEntries (no handler change needed)
Defensive patterns

Strategy: try-catch

Validate before calling

// Internal routing invariant; validate category queue before dispatch:
if (_currentCategory is not (CharacterDevelopmentCategory.Attribute or CharacterDevelopmentCategory.Weapon))
    throw new InvalidOperationException($"无法读取分类 {_currentCategory}。");

Try / catch

try { await ReadCategory(page); }
catch (InvalidOperationException ex) when (ex.Message.Contains("无法读取分类"))
{ /* this is a state-machine bug; fix SwitchCategory routing for Talent */ }

Prevention

When it happens

Trigger: `_pendingCategories` enqueues `Talent` and the state machine routes to `ReadCategory` instead of `FindTalentEntries`; `_currentCategory` left as `None` because `SwitchCategory` dequeued into the wrong branch.

Common situations: A bug in `SwitchCategory`/state transition registration; a custom transition table that sends Talent to `ReadCategory`; future enum additions not wired into the switch.

Related errors


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