HMCL-dev/HMCL · error · UnsupportedOperationException
grant flow
Error message
grant flow
What it means
OAuth.authenticate switches on the configured grantFlow. Only AUTHORIZATION_CODE and DEVICE are implemented; any other GrantFlow value reaches the default branch and throws UnsupportedOperationException. It marks an unimplemented enum value, typically from a custom or newly added flow.
Solutions
- Use GrantFlow.AUTHORIZATION_CODE or GrantFlow.DEVICE
- If you added a new GrantFlow value, implement its branch in OAuth.authenticate
- Log/inspect the configured flow value to confirm what is being passed
Example fix
// before new OAuth(GrantFlow.PASSWORD, options).authenticate(); // after new OAuth(GrantFlow.AUTHORIZATION_CODE, options).authenticate();
Defensive patterns
Strategy: validation
Validate before calling
if (grantFlow != GrantFlow.AUTHORIZATION_CODE && grantFlow != GrantFlow.DEVICE) {
throw new IllegalArgumentException("Unsupported grant flow: " + grantFlow);
} Type guard
boolean supported = grantFlow == GrantFlow.AUTHORIZATION_CODE || grantFlow == GrantFlow.DEVICE;
Try / catch
try {
return oauth.authenticate();
} catch (UnsupportedOperationException e) {
log.error("Grant flow not implemented: {}", e.getMessage());
} Prevention
- Restrict configuration to implemented GrantFlow values
- Add an enum completeness check/test over GrantFlow
- When adding enum constants, update the authenticate switch
When it happens
Trigger: Constructing an OAuth authenticator with a grantFlow other than AUTHORIZATION_CODE or DEVICE (e.g. CLIENT_CREDENTIALS or a custom enum constant) and calling authenticate.
Common situations: Adding a new GrantFlow enum constant without wiring it into authenticate; copy-pasted configuration selecting an unsupported flow.
Related errors
- Invalid theme color:
- Unsupported Operation
- Unsupported protected payload:
- Unsupported theme background type:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/a420657d1653220d.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OAuth.java:65
private final String deviceCodeURL;
private final String tokenURL;
public OAuth(String authorizationURL, String accessTokenURL, String deviceCodeURL, String tokenURL) {
this.authorizationURL = authorizationURL;
this.accessTokenURL = accessTokenURL;
this.deviceCodeURL = deviceCodeURL;
this.tokenURL = tokenURL;
}
public Result authenticate(GrantFlow grantFlow, Options options) throws AuthenticationException {
try {
switch (grantFlow) {
case AUTHORIZATION_CODE:
return authenticateAuthorizationCode(options);
case DEVICE:
return authenticateDevice(options);
default:
throw new UnsupportedOperationException("grant flow " + grantFlow);
}
} catch (IOException e) {
throw new ServerDisconnectException(e);
} catch (InterruptedException e) {
throw new NoSelectedCharacterException();
} catch (ExecutionException e) {
if (e.getCause() instanceof InterruptedException) {
throw new NoSelectedCharacterException();
} else {
throw new ServerDisconnectException(e);
}
} catch (JsonParseException e) {
throw new ServerResponseMalformedException(e);
}
}
private Result authenticateAuthorizationCode(Options options) throws IOException, InterruptedException, JsonParseException, ExecutionException, AuthenticationException {
try (Session session = options.callback.startServer()) {View on GitHub (pinned to 24702dc5a0)