{"record":{"id":"0104e996c8bdf477","repo":"HMCL-dev/HMCL","slug":"profile-name-is-missing-0104e9","errorCode":null,"errorMessage":"Profile name is missing","messagePattern":"Profile name is missing","errorType":"exception","errorClass":"ServerResponseMalformedException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java","lineNumber":125,"sourceCode":"            if (session.hasProfileName() && service.validate(session.getAccessToken(), session.getClientToken())) {\n                authenticated = true;\n            } else {\n                YggdrasilSession acquiredSession;\n                try {\n                    acquiredSession = service.refresh(session.getAccessToken(), session.getClientToken(), null);\n                } catch (RemoteAuthenticationException e) {\n                    if (\"ForbiddenOperationException\".equals(e.getRemoteName())) {\n                        throw new CredentialExpiredException(e);\n                    } else {\n                        throw e;\n                    }\n                }\n                if (acquiredSession.getSelectedProfile() == null ||\n                        !acquiredSession.getSelectedProfile().getId().equals(profileID)) {\n                    throw new ServerResponseMalformedException(\"Selected profile changed\");\n                }\n                if (!acquiredSession.hasProfileName()) {\n                    throw new ServerResponseMalformedException(\"Profile name is missing\");\n                }\n\n                session = acquiredSession;\n\n                authenticated = true;\n                invalidate();\n            }\n        }\n\n        return session.toAuthInfo();\n    }\n\n    @Override\n    public synchronized AuthInfo logInWithPassword(String password) throws AuthenticationException {\n        YggdrasilSession acquiredSession = service.authenticate(loginName, password, randomClientToken());\n\n        if (acquiredSession.getSelectedProfile() == null) {\n            if (acquiredSession.getAvailableProfiles() == null || acquiredSession.getAvailableProfiles().isEmpty()) {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilAccount.java#L107-L143","documentation":"YggdrasilAccount.logIn throws ServerResponseMalformedException(\"Profile name is missing\") when the acquired session has a selected profile but YggdrasilSession.hasProfileName() reports no name. A session without a profile name cannot produce valid game launch credentials, so HMCL rejects it.","triggerScenarios":"logIn() receiving a server response whose selectedProfile object contains an id but a null/missing \"name\" field, or a response with selectedProfile null after token validate/refresh.","commonSituations":"Broken third-party auth servers returning partial profile objects; proxies or API changes stripping the name field; authlib-injector backends with incomplete profile data.","solutions":["Check the auth server's /authenticate or /refresh response includes \"name\" in selectedProfile; fix the server if you control it.","Re-login from scratch (remove and re-add the account) to force a fresh full authentication.","Switch to a different authentication server implementation that returns complete profile objects."],"exampleFix":"// before (server response)\n{\"selectedProfile\":{\"id\":\"069a79f4...\"}}\n// after\n{\"selectedProfile\":{\"id\":\"069a79f4...\",\"name\":\"Notch\"}}","handlingStrategy":"try-catch","validationCode":"JsonObject selected = response.getAsJsonObject(\"selectedProfile\");\nif (selected == null || !selected.has(\"name\")) {\n    throw new IllegalStateException(\"Server returned selected profile without name\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    account.logIn();\n} catch (ServerResponseMalformedException e) {\n    // full re-login or switch to a functioning auth server\n    account.remove();\n}","preventionTips":["Audit third-party auth server responses for complete selectedProfile objects.","Re-add accounts that repeatedly fail login instead of retrying refresh.","Test authlib-injector backends with a real login before deployment."],"tags":["authentication","yggdrasil","session"],"backgroundTag":"unexpected-api-response-shape","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"}