babalae/better-genshin-impact · error · PartySetupFailedException

切换角色:{nextRole.Slot} 号位连续 {MaxRoleSwitchAttempts} 次未能切换为 {ne

Error message

切换角色:{nextRole.Slot} 号位连续 {MaxRoleSwitchAttempts} 次未能切换为 {nextRole.Name}

What it means

Thrown during the normal PrepareNextRole selection when a slot's retry budget is exhausted: the next role to switch (_requestedTargetRoles or _targetRoles) has _roleSwitchAttempts[slot] >= MaxRoleSwitchAttempts (3). The state machine could not switch that slot to the requested role in 3 tries.

Source

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

            _rebuildStartSlot = null;
        }

        if (_currentRole == null)
        {
            var currentNameBySlot = _currentTeamSlots.ToDictionary(slot => slot.Slot, slot => slot.Name);
            var nextRole = _requestedTargetRoles
                .OrderBy(role => role.Slot)
                .FirstOrDefault(role =>
                    !currentNameBySlot.TryGetValue(role.Slot, out var currentName) || !role.Matches(currentName))
                ?? _targetRoles
                .OrderBy(role => role.Slot)
                .FirstOrDefault(role =>
                    !currentNameBySlot.TryGetValue(role.Slot, out var currentName) || !role.Matches(currentName));
            if (nextRole != null)
            {
                if (_roleSwitchAttempts.GetValueOrDefault(nextRole.Slot) >= MaxRoleSwitchAttempts)
                {
                    throw new PartySetupFailedException(
                        $"切换角色:{nextRole.Slot} 号位连续 {MaxRoleSwitchAttempts} 次未能切换为 {nextRole.Name}");
                }

                SetCurrentRole(nextRole);
            }
        }

        if (_currentRole == null)
        {
            if (_needsFinalVerification)
            {
                _logger.LogDebug("切换角色:所有目标已提交,开始统一识别并验证实际队伍");
                _teamSnapshotDirty = true;
                return StateHandlerResult.Wait;
            }

            _workflowState = SwitchCharacterState.ReturnMainUi;
            return StateHandlerResult.Success;

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the role name is owned and that ToConfiguredAvatarName/alias resolution yields a valid avatar.
  2. Check Recognizer.GetWeaponType/GetElementType for the role — a wrong filter excludes it from the grid.
  3. Increase MaxRoleSwitchAttempts or downgrade the failure to a skip-and-continue for non-critical slots.
  4. Log the recognized slot name each attempt to pinpoint whether selection or recognition is failing.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate roster ownership and alias resolution before starting
foreach (var name in new[] { slot1, slot2, slot3, slot4 }.Where(s => !string.IsNullOrWhiteSpace(s)))
{
    var standard = ToConfiguredAvatarName(name.Trim());
    if (!DefaultAutoFightConfig.CombatAvatarMap.ContainsKey(standard) && !IsOwnedAvatar(standard))
        throw new ArgumentException($"账号未拥有角色:{standard}");
}

Type guard

static bool RoleIsOwned(string name)
{
    var standard = ToConfiguredAvatarName(name.Trim());
    return DefaultAutoFightConfig.CombatAvatarMap.ContainsKey(standard) || IsOwnedAvatar(standard);
}

Try / catch

try { await sm.Start(s1, s2, s3, s4, usePhysicalSlots, ct); }
catch (PartySetupFailedException e) when (e.Message.Contains("未能切换为"))
{ /* degrade gracefully: skip the slot or surface a user-facing warning */ }

Prevention

When it happens

Trigger: In HandlePrepareNextRole, with _currentRole == null, a mismatched nextRole is found and _roleSwitchAttempts[nextRole.Slot] >= 3. Across 3 OpenFilterPanel->select->save cycles the slot never settled on a role that Matches(nextRole).

Common situations: The role is not owned; the element/weapon filter for the role is mis-detected so it never appears in the grid; AvatarGridIconRecognizer mis-reads the placed icon; alias resolution produced a name absent from the roster; a UI transition was dropped so the save never committed.

Related errors


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