{"record":{"id":"17238b1028387724","repo":"HMCL-dev/HMCL","slug":"failed-to-select-character","errorCode":null,"errorMessage":"Failed to select character","messagePattern":"Failed to select character","errorType":"exception","errorClass":"ServerResponseMalformedException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilService.java","lineNumber":116,"sourceCode":"    public YggdrasilSession refresh(String accessToken, String clientToken, GameProfile characterToSelect) throws AuthenticationException {\n        Objects.requireNonNull(accessToken);\n        Objects.requireNonNull(clientToken);\n\n        Map<String, Object> request = createRequestWithCredentials(accessToken, clientToken);\n        request.put(\"requestUser\", true);\n\n        if (characterToSelect != null) {\n            request.put(\"selectedProfile\", mapOf(\n                    pair(\"id\", UUIDs.toCompactString(characterToSelect.getId())),\n                    pair(\"name\", characterToSelect.getName())));\n        }\n\n        YggdrasilSession response = handleAuthenticationResponse(request(provider.getRefreshmentURL(), request), clientToken);\n\n        if (characterToSelect != null) {\n            if (response.getSelectedProfile() == null ||\n                    !response.getSelectedProfile().getId().equals(characterToSelect.getId())) {\n                throw new ServerResponseMalformedException(\"Failed to select character\");\n            }\n        }\n\n        return response;\n    }\n\n    public boolean validate(String accessToken) throws AuthenticationException {\n        return validate(accessToken, null);\n    }\n\n    public boolean validate(String accessToken, String clientToken) throws AuthenticationException {\n        Objects.requireNonNull(accessToken);\n\n        try {\n            requireEmpty(request(provider.getValidationURL(), createRequestWithCredentials(accessToken, clientToken)));\n            return true;\n        } catch (RemoteAuthenticationException e) {\n            if (\"ForbiddenOperationException\".equals(e.getRemoteName())) {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilService.java#L98-L134","documentation":"YggdrasilService.refresh throws ServerResponseMalformedException(\"Failed to select character\") when a characterToSelect was requested but the refresh response's selectedProfile is null or has a different id. It means the server did not (or could not) bind the refreshed token to the requested character.","triggerScenarios":"Calling refresh(token, characterToSelect) where the character was deleted/renamed on the server, or the server ignores the selectedCharacter hint in its /refresh response.","commonSituations":"Switching characters on an authlib-injector server whose backend deleted the old one; account kept on another machine while the character was removed; server implementations not honoring the selectedCharacter field.","solutions":["Re-authenticate (authenticate instead of refresh) and re-select a currently available character from availableProfiles.","Pass null as characterToSelect if you don't require a specific character after refresh.","Verify the character still exists on the auth server and re-add the account bound to a valid one."],"exampleFix":"// before\nservice.refresh(accessToken, oldCharacter); // throws if character gone\n// after\ntry {\n    service.refresh(accessToken, oldCharacter);\n} catch (ServerResponseMalformedException e) {\n    YggdrasilSession fresh = service.authenticate(username, password);\n    // reselect from fresh.getAvailableProfiles()\n}","handlingStrategy":"try-catch","validationCode":"if (characterToSelect != null &&\n    !availableProfileIds().contains(characterToSelect.getId())) {\n    // character no longer exists server-side; skip selection\n    characterToSelect = null;\n}","typeGuard":null,"tryCatchPattern":"try {\n    service.refresh(accessToken, characterToSelect);\n} catch (ServerResponseMalformedException e) {\n    // re-authenticate and reselect from availableProfiles\n    YggdrasilSession fresh = service.authenticate(username, password);\n}","preventionTips":["Confirm the character still exists before calling refresh with a selection.","Fetch availableProfiles after refresh failures to see valid characters.","Avoid sharing one account across machines that may delete characters."],"tags":["authentication","yggdrasil","session"],"backgroundTag":"entity-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}