{"record":{"id":"ec8165666a5d2526","repo":"babalae/better-genshin-impact","slug":"error-ec8165","errorCode":null,"errorMessage":"切换角色：筛选面板缺少武器筛选项","messagePattern":"切换角色：筛选面板缺少武器筛选项","errorType":"exception","errorClass":"PartySetupFailedException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs","lineNumber":740,"sourceCode":"    /// <returns>点击筛选入口后返回 Success。</returns>\n    [StateHandler(SwitchCharacterState.OpenFilterPanel, RetryTimeout = 9000, RetryInterval = 300, TransitionTimeout = 4000)]\n    private Task<StateHandlerResult> HandleOpenFilterPanel(BvPage page)\n    {\n        GameCaptureRegion.GameRegion1080PPosClick(66, 46);\n        return Task.FromResult(StateHandlerResult.Success);\n    }\n\n    /// <summary>\n    /// 处理筛选面板。\n    /// </summary>\n    /// <param name=\"page\">页面操作对象。</param>\n    /// <returns>根据当前角色筛选需求进入元素或武器筛选状态。</returns>\n    [StateHandler(SwitchCharacterState.FilterPanel, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 6000)]\n    private Task<StateHandlerResult> HandleFilterPanel(BvPage page)\n    {\n        if (string.IsNullOrWhiteSpace(_pendingFilterWeaponType))\n        {\n            throw new PartySetupFailedException(\"切换角色：筛选面板缺少武器筛选项\");\n        }\n\n        _workflowState = string.IsNullOrWhiteSpace(_pendingFilterElementType)\n            ? SwitchCharacterState.SelectWeaponFilter\n            : SwitchCharacterState.SelectElementFilter;\n        return Task.FromResult(StateHandlerResult.Success);\n    }\n\n    /// <summary>\n    /// 选择元素筛选项。\n    /// </summary>\n    /// <param name=\"page\">页面操作对象。</param>\n    /// <returns>点击元素选项后进入武器筛选；找不到选项时返回 Retry。</returns>\n    [StateHandler(SwitchCharacterState.SelectElementFilter, RetryTimeout = 12000, RetryInterval = 300, TransitionTimeout = 3000)]\n    private Task<StateHandlerResult> HandleSelectElementFilter(BvPage page)\n    {\n        if (string.IsNullOrWhiteSpace(_pendingFilterElementType))\n        {","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs#L722-L758","documentation":"Thrown by HandleFilterPanel as a hard invariant guard: the filter panel handler was reached but _pendingFilterWeaponType is null/empty. The weapon type is normally populated by SetCurrentRoleFilter from AvatarGridIconRecognizer.GetWeaponType(role.PrimaryCandidateName); if that lookup yielded nothing the whole filter workflow is invalid, so it fails fast instead of clicking blindly.","triggerScenarios":"SetCurrentRole(role) ran but Recognizer.GetWeaponType(PrimaryCandidateName) returned null/whitespace, leaving _pendingFilterWeaponType empty when the state machine later transitions into SwitchCharacterState.FilterPanel.","commonSituations":"The requested character name is not present in the recognizer's weapon-type metadata table (typo, alias not registered, newly released character not yet added); the PrimaryCandidateName resolved from CandidateNames[0] is a display alias the recognizer does not map; ForcedWeaponType was left null for a custom role and GetWeaponType returned empty.","solutions":["Check that the character name passed to Start matches an entry known to AvatarGridIconRecognizer.GetWeaponType; register the missing character/alias in the recognizer metadata.","Supply ForcedWeaponType explicitly when constructing TargetRole for characters whose weapon type is ambiguous or unmapped.","Validate _pendingFilterWeaponType in SetCurrentRoleFilter and throw there with the offending character name for a clearer failure point."],"exampleFix":"// before\n_pendingFilterWeaponType = role.ForcedWeaponType ?? Recognizer.GetWeaponType(role.PrimaryCandidateName);\n\n// after\n_pendingFilterWeaponType = role.ForcedWeaponType ?? Recognizer.GetWeaponType(role.PrimaryCandidateName);\nif (string.IsNullOrWhiteSpace(_pendingFilterWeaponType))\n{\n    throw new PartySetupFailedException($\"切换角色：无法解析 {role.PrimaryCandidateName} 的武器类型\");\n}","handlingStrategy":"validation","validationCode":"foreach (var role in roles)\n{\n    var weapon = role.ForcedWeaponType ?? recognizer.GetWeaponType(role.PrimaryCandidateName);\n    if (string.IsNullOrWhiteSpace(weapon))\n    {\n        throw new ArgumentException($\"角色 {role.PrimaryCandidateName} 缺少武器类型映射，无法进入筛选\");\n    }\n}","typeGuard":"static bool HasWeaponType(TargetRole role, AvatarGridIconRecognizer recognizer)\n    => !string.IsNullOrWhiteSpace(role.ForcedWeaponType\n        ?? recognizer.GetWeaponType(role.PrimaryCandidateName));","tryCatchPattern":"try { await switchTask.Start(...); }\ncatch (PartySetupFailedException ex) when (ex.Message.Contains(\"筛选面板缺少武器筛选项\"))\n{ _logger.LogError(ex, \"角色武器类型未配置，请补充识别器元数据或 ForcedWeaponType\"); }","preventionTips":["Register every requested character in AvatarGridIconRecognizer's weapon-type map.","Set ForcedWeaponType on TargetRole for custom/ambiguous characters.","Validate weapon-type resolution up front in Start before running the state machine."],"tags":["party-setup","state-machine","invariant","character-metadata","switch-character"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}