babalae/better-genshin-impact · error · PartySetupFailedException

切换角色:换下错位角色后无法确定需要补回的槽位

Error message

切换角色:换下错位角色后无法确定需要补回的槽位

What it means

Thrown during HandlePrepareNextRole after a misplaced role was removed (_prepareSuffixRebuildAfterRemoval) when FindFirstMismatchSlot returns null — i.e. the freshly-recognized current team already satisfies all target slots, so the state machine cannot decide which slot to rebuild from.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs:604

    private async Task<StateHandlerResult> HandlePrepareNextRole(BvPage page)
    {
        if (_teamSnapshotDirty)
        {
            _currentTeamSlots = await RecognizeTeamSlotsFromCharacterList(Recognizer, _expectedTeamCount, _ct);
            _teamSnapshotDirty = false;
            if (_needsFinalVerification)
            {
                _logger.LogInformation("切换角色:已完成最终队伍识别,按实际队伍继续验证目标槽位");
                _needsFinalVerification = false;
            }
        }

        if (_prepareSuffixRebuildAfterRemoval)
        {
            var firstMismatchSlot = FindFirstMismatchSlot(_targetRoles, _currentTeamSlots);
            if (firstMismatchSlot == null)
            {
                throw new PartySetupFailedException("切换角色:换下错位角色后无法确定需要补回的槽位");
            }

            StartSuffixRebuild(firstMismatchSlot.Value);
            _prepareSuffixRebuildAfterRemoval = false;
        }

        if (_rebuildStartSlot is int rebuildStartSlot)
        {
            var minimumRetainedCount = Math.Max(1, rebuildStartSlot - 1);
            if (_isRebuildClearing && _currentTeamSlots.Count > minimumRetainedCount)
            {
                ClickFixedTeamSlot(rebuildStartSlot);
                await Delay(500, _ct);
                if (!TryClickText(page, "换下", Rect1080(382, 994, 87, 51)))
                {
                    throw new PartySetupFailedException($"切换角色:未找到 {rebuildStartSlot} 号位的换下按钮");
                }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. When FindFirstMismatchSlot is null after a removal, treat the team as complete and transition to completion instead of throwing.
  2. Re-run RecognizeTeamSlotsFromCharacterList once more to rule out a transient recognition error before deciding.
  3. Loosen/verify the TargetRole.Matches logic so a near-name does not falsely satisfy a slot.
  4. Log _currentTeamSlots vs _targetRoles at this point to diagnose the false-match.

Example fix

// before
var firstMismatchSlot = FindFirstMismatchSlot(_targetRoles, _currentTeamSlots);
if (firstMismatchSlot == null)
{
    throw new PartySetupFailedException("切换角色:换下错位角色后无法确定需要补回的槽位");
}
StartSuffixRebuild(firstMismatchSlot.Value);

// after: a null mismatch means the team already matches -> proceed
var firstMismatchSlot = FindFirstMismatchSlot(_targetRoles, _currentTeamSlots);
if (firstMismatchSlot == null)
{
    _logger.LogInformation("切换角色:换下错位角色后队伍已满足目标,跳过补回");
    _workflowState = SwitchCharacterState.ReturnMainUi;
    return StateHandlerResult.Success;
}
StartSuffixRebuild(firstMismatchSlot.Value);
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

try { await sm.Start(s1, s2, s3, s4, usePhysicalSlots, ct); }
catch (PartySetupFailedException e) when (e.Message.Contains("无法确定需要补回的槽位"))
{ /* re-recognize the team; if it matches targets, accept; else restart the switch */ }

Prevention

When it happens

Trigger: _prepareSuffixRebuildAfterRemoval is true, the team is re-recognized, but FindFirstMismatchSlot(_targetRoles, _currentTeamSlots) returns null (no mismatch). The machine expected to refill a cleared suffix but the targets already match, leaving no rebuild anchor.

Common situations: Team recognition mis-identified a role as already matching (OCR/recognizer false positive) right after the removal; target roles were satisfied by the retained prefix unexpectedly; a race where _targetRoles was mutated; recognizer returned a name that Matches() the target by alias coincidence.

Related errors


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