{"record":{"id":"efbc309479d772f8","repo":"babalae/better-genshin-impact","slug":"error-efbc30","errorCode":null,"errorMessage":"选择队伍失败，等待队伍切换超时！","messagePattern":"选择队伍失败，等待队伍切换超时！","errorType":"exception","errorClass":"PartySetupFailedException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/SwitchPartyTask.cs","lineNumber":245,"sourceCode":"\n        // 未找到\n        Logger.LogError(\"未找到队伍: {Name}，返回主界面\", partyName);\n        Logger.LogInformation(\"如果找不到设定的队伍名，有可能是文字识别效果不佳，请尝试正则表达式\");\n        await _returnMainUiTask.Start(ct);\n        return false;\n    }\n\n    private async Task ConfirmParty(ImageRegion page, CancellationToken ct, bool isInPartyViewUi = false)\n    {\n        var r1 = Bv.ClickWhiteConfirmButton(page, new Rect(0, page.Height / 4, page.Width / 4, page.Height - page.Height / 4));\n        var partyChooseUiClosed = await NewRetry.WaitForAction(() =>\n        {\n            using var ra2 = CaptureToRectArea();\n            return ra2.Find(ElementRecognition.Get(\"PartyBtnDelete\", ra2)).IsEmpty();\n        }, ct, 10);\n        if (!partyChooseUiClosed)\n        {\n            throw new PartySetupFailedException(\"选择队伍失败，等待队伍切换超时！\");\n        }\n        await Delay(200, ct);\n        using var ra = CaptureToRectArea();\n        var r2 = Bv.ClickWhiteConfirmButton(ra, new Rect(page.Width - page.Width / 4, page.Height / 4, page.Width / 4, page.Height - page.Height / 4));\n        await Delay(500, ct);\n        if (isInPartyViewUi) await _returnMainUiTask.Start(ct);\n    }\n}\n","sourceCodeStart":227,"sourceCodeEnd":254,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/SwitchPartyTask.cs#L227-L254","documentation":"Thrown by SwitchPartyTask.ConfirmParty after clicking the party-confirm button when the party-selection UI ('PartyBtnDelete' element) remains visible. NewRetry.WaitForAction polls up to 10 times (default 1000ms interval) for the delete-button element to disappear; if it never does, the UI never closed and the party switch is considered failed. It is a PartySetupFailedException (a plain Exception subclass), indicating an automation-flow failure against the live game UI, not a programming error.","triggerScenarios":"Called from ConfirmParty after SelectParty finds the target party name and clicks it. WaitForAction repeatedly calls CaptureToRectArea() + ElementRecognition.Get(\"PartyBtnDelete\", ra2).IsEmpty(). If the in-game confirm click missed (wrong coords), the game was lagging, the UI changed in a game update, or an unrelated dialog obscured the screen, the element stays visible for all 10 retries.","commonSituations":"Game version update moved/renamed the party-delete button template; the confirm-button click region Rect(0, height/4, width/4, ...) no longer overlaps the real button at the current resolution/scale; game running slowly so the UI-close animation exceeds the poll budget; another popup (e.g. network notice) is open; resolution or _assetScale mismatch.","solutions":["Verify the game is on a supported version and the party UI looks as expected; close any overlaying dialogs before running.","Confirm the capture resolution and _assetScale match the design assumptions so the confirm-button click lands correctly.","Increase the retry count or delay passed to NewRetry.WaitForAction (currently 10 retries) if the close animation is slow.","Re-capture/update the 'PartyBtnDelete' element template under Assets if a game update changed its appearance.","Check logs for the '截图失败' warning — if captures are failing, fix the capture backend first."],"exampleFix":"// before\nvar partyChooseUiClosed = await NewRetry.WaitForAction(() =>\n{\n    using var ra2 = CaptureToRectArea();\n    return ra2.Find(ElementRecognition.Get(\"PartyBtnDelete\", ra2)).IsEmpty();\n}, ct, 10);\n\n// after — give the close animation more time and log on each miss\nvar partyChooseUiClosed = await NewRetry.WaitForAction(() =>\n{\n    using var ra2 = CaptureToRectArea();\n    var btn = ra2.Find(ElementRecognition.Get(\"PartyBtnDelete\", ra2));\n    if (!btn.IsEmpty()) Logger.LogWarning(\"队伍选择界面仍未关闭\");\n    return btn.IsEmpty();\n}, ct, 20, 800);","handlingStrategy":"try-catch","validationCode":"// Before switching party, confirm the game is in the party view and the confirm button region is on screen\nusing var region = CaptureToRectArea();\nif (region.Find(ElementRecognition.Get(\"PartyBtnDelete\", region)).IsEmpty())\n{\n    Logger.LogWarning(\"未处于队伍选择界面，跳过确认\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await ConfirmParty(page, ct, isInPartyViewUi);\n}\ncatch (PartySetupFailedException ex)\n{\n    Logger.LogError(ex, \"队伍切换超时，尝试返回主界面\");\n    await _returnMainUiTask.Start(ct);\n    throw; // or return false to signal caller\n}","preventionTips":["Keep the game on a supported version and update element templates after patches.","Verify capture resolution and _assetScale before running party-switch flows.","Close overlaying dialogs before invoking the flow."],"tags":["game-automation","ui-recognition","retry-timeout","party-switch"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}