justauth/JustAuth · error · AuthException

${errorCode}

${errorCode}

Error message

${errorMsg}

What it means

AuthWechatMiniProgramRequest.checkResponse takes the deserialized JSCode2SessionResponse (from the jscode2session endpoint of a WeChat Mini Program) and throws AuthException(errorCode, errorMsg) whenever errorCode != 0. The exception's numeric code is WeChat's own error code, the message its errmsg. Note it triggers only on non-zero codes — a successful session returns 0/absent code.

Source

Thrown at src/main/java/me/zhyd/oauth/request/AuthWechatMiniProgramRequest.java:70

        // 如果需要用户信息,需要在小程序调用函数后传给后端
        return AuthUser.builder()
            .username("")
            .nickname("")
            .avatar("")
            .uuid(authToken.getOpenId())
            .token(authToken)
            .source(source.toString())
            .build();
    }

    /**
     * 检查响应内容是否正确
     *
     * @param response 请求响应内容
     */
    private void checkResponse(JSCode2SessionResponse response) {
        if (response.getErrorCode() != 0) {
            throw new AuthException(response.getErrorCode(), response.getErrorMsg());
        }
    }

    @Override
    protected String accessTokenUrl(String code) {
        return UrlBuilder.fromBaseUrl(source.accessToken())
            .queryParam("appid", config.getClientId())
            .queryParam("secret", config.getClientSecret())
            .queryParam("js_code", code)
            .queryParam("grant_type", "authorization_code")
            .build();
    }

    @Data
    @SuppressWarnings("SpellCheckingInspection")
    private static class JSCode2SessionResponse {

        @JSONField(name = "errcode")

View on GitHub (pinned to 694bbf1b01)

Solutions

  1. Check e.getCode(): 40029 → dedupe js_code submissions (idempotency key on the login endpoint); 40164 → whitelist the backend IP in the mini program console (开发管理>开发设置>服务器域名/IP名单); 40125 → fix the appsecret.
  2. Ensure AuthConfig uses the mini program's AppID + AppSecret pair, not the bound official account's.
  3. Submit js_code to your backend immediately and exchange it once; treat code as single-use.
  4. Cache session_key/openid per openid instead of re-running jscode2session.
Defensive patterns

Strategy: try-catch

Validate before calling

// idempotent login endpoint: one js_code, one exchange
String key = "jscode:" + req.getJsCode();
if (!redis.setnx(key, "1", Duration.ofMinutes(10))) {
    return cachedSession(req.getJsCode()); // duplicate submit
}

Try / catch

try {
    AuthUser u = mpRequest.login(callback);
} catch (AuthException e) {
    switch (e.getCode()) {
        case 40029: return ResponseEntity.status(409).body("code already used or invalid, call wx.login() again");
        case 40164: throw new ConfigurationException("whitelist backend IP", e);
        case 40125: throw new ConfigurationException("check mini-program appSecret", e);
        default: throw e;
    }
}

Prevention

When it happens

Trigger: jscode2session call failing: invalid js_code from wx.login() (40029 — already used, expired ~5min, or from a different mini program), invalid appid/secret pairing (40125), IP not in the mini program's whitelist (40164), or rate limiting (45011).

Common situations: Frontend calls wx.login() but the code is sent to the backend twice (duplicate HTTP retry) — second exchange returns 40029; appid of the mini program mixed up with the official account's appid; backend deployed to a new IP without updating the whitelist; dev tools issuing codes for a different environment.

Related errors


AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14). Data as JSON: /api/errors/f23053d73f84ba5a. Report an issue: GitHub.