justauth/JustAuth · error · AuthException
JSONObject.toJSONString(response)
Error message
JSONObject.toJSONString(response)
What it means
The DingTalk v2 adapter posts grantType=authorization_code and expects an 'accessToken' field in the JSON response; when that key is absent it throws AuthException whose message is the entire raw response body. So the exception text is DingTalk's own error payload (errcode/errmsg style), which tells you why the exchange failed.
Source
Thrown at src/main/java/me/zhyd/oauth/request/AuthDingTalkV2Request.java:62
.queryParam("org_type", config.getDingTalkOrgType())
.queryParam("corpId", config.getDingTalkCorpId())
.queryParam("exclusiveLogin", config.isDingTalkExclusiveLogin())
.queryParam("exclusiveCorpId", config.getDingTalkExclusiveCorpId())
.queryParam("state", getRealState(state))
.build();
}
@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
Map<String, String> params = new HashMap<>();
params.put("grantType", "authorization_code");
params.put("clientId", config.getClientId());
params.put("clientSecret", config.getClientSecret());
params.put("code", authCallback.getCode());
String response = new HttpUtils(config.getHttpConfig()).post(this.source.accessToken(), JSONObject.toJSONString(params)).getBody();
JSONObject accessTokenObject = JSONObject.parseObject(response);
if (!accessTokenObject.containsKey("accessToken")) {
throw new AuthException(JSONObject.toJSONString(response), source);
}
return AuthToken.builder()
.accessToken(accessTokenObject.getString("accessToken"))
.refreshToken(accessTokenObject.getString("refreshToken"))
.expireIn(accessTokenObject.getIntValue("expireIn"))
.corpId(accessTokenObject.getString("corpId"))
.build();
}
@Override
public AuthUser getUserInfo(AuthToken authToken) {
HttpHeader header = new HttpHeader();
header.add("x-acs-dingtalk-access-token", authToken.getAccessToken());
String response = new HttpUtils(config.getHttpConfig()).get(this.source.userInfo(), null, header, false).getBody();
JSONObject object = JSONObject.parseObject(response);
authToken.setOpenId(object.getString("openId"));View on GitHub (pinned to 694bbf1b01)
Solutions
- Read the thrown message - it is DingTalk's raw JSON, e.g. {"errcode":40035,"errmsg":"invalid code"} - and act on the errmsg.
- Ensure the code from authCallback.getCode() is exchanged exactly once, immediately after redirect (store state to dedupe).
- Verify the DingTalk app's clientId (AppKey)/clientSecret (AppSecret) match the current credentials.
- If errmsg mentions IP restrictions, add your server's egress IP to the DingTalk app's server whitelist.
Defensive patterns
Strategy: try-catch
Try / catch
try {
return dingTalkRequest.getAccessToken(callback);
} catch (AuthException e) {
// message is DingTalk's raw JSON body, e.g. {"errcode":40035,"errmsg":"invalid code"}
log.warn("DingTalk token error: {}", e.getErrorMsg());
if (e.getErrorMsg() != null && e.getErrorMsg().contains("invalid code")) {
return reauthorizeResponse();
}
throw e;
} Prevention
- Exchange the DingTalk authCode within seconds of the callback and never twice - it is single-use.
- Keep AppKey/AppSecret in sync with the DingTalk developer console after rotations.
- Whitelist your server egress IPs in the DingTalk app if you see IP-related errmsg values.
When it happens
Trigger: getAccessToken(AuthCallback) with a wrong clientId/clientSecret pair, an authorization code that was already redeemed or expired (DingTalk codes are single-use and short-lived), or a server-side error where DingTalk returns errcode without accessToken.
Common situations: User refreshes the callback page causing the code to be exchanged twice; DingTalk app credentials rotated; system clock skew; or dev environment reaching DingTalk through a proxy that mangles the POST body.
Related errors
- object.getString("error") + ":" + object.getString("message"
- errorDescription
- object.getString("error_description")
- ${errmsg}
- object.getString("error_description") / object.getString("er
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/0387cbe18624a9ca.
Report an issue: GitHub.