alibaba/spring-ai-alibaba · error · BizException
Oauth2UserNotFound
Oauth2UserNotFound
Error message
Oauth2 user can not be found.
What it means
Thrown by AccountServiceImpl.login(Oauth2User) when the OAuth2 user object is null or its userId is blank. The method has no identity to authenticate or auto-register against, so it fails fast. It reflects an upstream OAuth2 provider response that did not yield a usable user id.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-core/src/main/java/com/alibaba/cloud/ai/studio/core/base/service/impl/AccountServiceImpl.java:144
* @param refreshTokenRequest Refresh token request
* @return New token response
*/
@Override
public TokenResponse refreshToken(RefreshTokenRequest refreshTokenRequest) {
String accountId = tokenManager.getAccountIdFromRefreshToken(refreshTokenRequest.getRefreshToken());
if (accountId == null) {
throw new BizException(ErrorCode.INVALID_REFRESH_TOKEN.toError());
}
TokenResponse response = createTokenResponse(accountId);
tokenManager.deleteRefreshToken(refreshTokenRequest.getRefreshToken());
return response;
}
@Override
public TokenResponse login(Oauth2User oauth2User) {
if (oauth2User == null || StringUtils.isBlank(oauth2User.getUserId())) {
throw new BizException(ErrorCode.OAUTH2_USER_NOT_FOUND.toError());
}
String accountId;
AccountEntity accountEntity = getAccountByName(oauth2User.getUserId());
if (accountEntity == null) {
Account account = new Account();
account.setUsername(oauth2User.getUserId());
account.setNickname(oauth2User.getName());
account.setEmail(oauth2User.getEmail());
account.setIcon(oauth2User.getIcon());
account.setPassword(IdGenerator.uuid32());
accountId = registerAccount(account);
accountEntity = getAccountById(accountId);
}
else {
accountId = accountEntity.getAccountId();
}View on GitHub (pinned to f82da0b50f)
Solutions
- Fix the OAuth2 mapping so the provider's user id claim (sub/id) is copied into Oauth2User.userId before calling login.
- Check the upstream OAuth2 token/userinfo exchange result and handle its errors before constructing Oauth2User.
- Verify OAuth2 client scopes include the identifier claim and the provider is correctly configured.
- Log/inspect the raw provider response to confirm the expected fields are returned.
Example fix
// before
Oauth2User user = new Oauth2User();
user.setName(profile.getName());
tokenResponse = accountService.login(user); // userId blank -> BizException
// after
Oauth2User user = new Oauth2User();
user.setUserId(profile.getId());
user.setName(profile.getName());
if (user.getUserId() == null || user.getUserId().isBlank()) {
throw new IllegalStateException("Provider did not return a user id");
}
tokenResponse = accountService.login(user); Defensive patterns
Strategy: validation
Validate before calling
if (oauth2User == null || oauth2User.getUserId() == null || oauth2User.getUserId().isBlank()) {
throw new IllegalArgumentException("OAuth2 provider did not return a userId");
} Type guard
boolean isValidOauth2User(Oauth2User u) {
return u != null && u.getUserId() != null && !u.getUserId().isBlank();
} Try / catch
try {
return accountService.login(oauth2User);
} catch (BizException e) {
if ("Oauth2UserNotFound".equals(e.getCode())) {
return Response.status(401).entity("OAuth2 provider did not return a user id").build();
}
throw e;
} Prevention
- Validate the provider's userinfo response (id/sub present) before mapping to Oauth2User.
- Handle OAuth2 token-exchange failures explicitly instead of propagating a null/empty user.
- Configure client scopes so the identifier claim is always returned.
- Unit-test the provider-to-Oauth2User mapper with real provider payloads.
When it happens
Trigger: Passing a null Oauth2User into login, or an Oauth2User built from a provider response where the userId field is null/empty (e.g. provider returned an error payload or a differently shaped response).
Common situations: Misconfigured OAuth2 client (wrong scopes) so the id claim is absent; provider API change returning a different JSON shape; upstream token exchange failed silently and a null user was propagated into the service; custom auth code passing the raw profile without mapping userId.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/3041325ccc4a41f5.
Report an issue: GitHub.