{"record":{"id":"f76302973b054afd","repo":"babalae/better-genshin-impact","slug":"error-f76302","errorCode":null,"errorMessage":"切换角色：角色列表关闭后未返回队伍配置页","messagePattern":"切换角色：角色列表关闭后未返回队伍配置页","errorType":"exception","errorClass":"PartySetupFailedException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs","lineNumber":1439,"sourceCode":"                    characterNames.Add(candidate.Score >= MatchThreshold ? candidate.CharacterName : null);\n                }\n\n                break;\n            }\n        }\n        finally\n        {\n            Simulation.SendInput.Keyboard.KeyPress(Vanara.PInvoke.User32.VK.VK_ESCAPE);\n        }\n\n        var returned = await NewRetry.WaitForAction(() =>\n        {\n            using var capture = CaptureToRectArea();\n            return IsPartyConfigPage(capture);\n        }, ct, 10, 300);\n        if (!returned)\n        {\n            throw new PartySetupFailedException(\"切换角色：角色列表关闭后未返回队伍配置页\");\n        }\n\n        if (characterNames.Count != expectedTeamCount || characterNames.Any(string.IsNullOrEmpty))\n        {\n            throw new PartySetupFailedException(\n                $\"切换角色：角色列表队伍识别不完整，期望 {expectedTeamCount} 个，\" +\n                $\"末次检测到 {lastDetectedCardCount} 张卡片，成功识别 {characterNames.Count(name => name != null)} 个头像\");\n        }\n\n        var result = characterNames\n            .Select((name, index) => new TeamSlotSnapshot(index + 1, name))\n            .ToList();\n        _logger.LogDebug(\n            \"切换角色：当前账号可控角色 {ControlCount} 个，生成 {SnapshotCount} 项队伍快照，映射 {SlotMapping}\",\n            _maxControlAvatarCount,\n            result.Count,\n            string.Join(\",\", _logicalToPhysicalSlot\n                .OrderBy(pair => pair.Key)","sourceCodeStart":1421,"sourceCodeEnd":1457,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs#L1421-L1457","documentation":"After the card-recognition loop, RecognizeTeamSlotsFromCharacterList presses ESCAPE to close the list and waits up to 10x300ms for IsPartyConfigPage to confirm the party-config page returned. If the list did not close back to party config, the snapshot flow is aborted because the next steps assume party-config context.","triggerScenarios":"NewRetry.WaitForAction(() => IsPartyConfigPage(capture)) returns false after 10 attempts following the VK_ESCAPE keypress in the finally block.","commonSituations":"ESCAPE did not register (input focus elsewhere, game busy); the list closed to a different screen (e.g. main UI) instead of party config; IsPartyConfigPage detector text/ROI changed in a game update; a transition animation exceeded the budget.","solutions":["Confirm IsPartyConfigPage's detector (title text/ROI) still matches the current party-config layout.","Ensure ESCAPE input is reaching the game (check Simulation.SendInput focus) — re-send if needed.","Increase the 10x300ms budget if the close animation is slow.","If the list closes to main UI, re-open party config before retrying recognition."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await switchTask.Start(...); }\ncatch (PartySetupFailedException ex) when (ex.Message.Contains(\"未返回队伍配置页\"))\n{ _logger.LogWarning(ex, \"角色列表关闭后未回到队伍配置页，建议重试\"); }","preventionTips":["Confirm IsPartyConfigPage detector matches the current layout.","Ensure ESCAPE input reaches the game (focus).","Budget enough time for the close animation."],"tags":["party-setup","ui-automation","ocr","timeout","switch-character"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}