langgenius/dify · error · BadRequest

code is required

Error message

code is required

What it means

Flask BadRequest (HTTP 400) at oauth_server.py:208 in the AUTHORIZATION_CODE branch of the token endpoint. The grant_type was valid but payload.code is empty/None, so there is no authorization code to exchange. Raised before client_secret and redirect_uri are checked.

Source

Thrown at api/controllers/console/auth/oauth_server.py:208

        )


@console_ns.route("/oauth/provider/token")
class OAuthServerUserTokenApi(Resource):
    @setup_required
    @console_ns.expect(console_ns.models[OAuthTokenRequest.__name__])
    @console_ns.response(200, "Success", console_ns.models[OAuthProviderTokenResponse.__name__])
    @oauth_server_client_id_required
    @model_validate(OAuthTokenRequest)
    def post(self, payload: OAuthTokenRequest, oauth_provider_app: OAuthProviderApp):
        try:
            grant_type = OAuthGrantType(payload.grant_type)
        except ValueError:
            raise BadRequest("invalid grant_type")
        match grant_type:
            case OAuthGrantType.AUTHORIZATION_CODE:
                if not payload.code:
                    raise BadRequest("code is required")

                if payload.client_secret != oauth_provider_app.client_secret:
                    raise BadRequest("client_secret is invalid")

                if payload.redirect_uri not in oauth_provider_app.redirect_uris:
                    raise BadRequest("redirect_uri is invalid")

                access_token, refresh_token = OAuthServerService.sign_oauth_access_token(
                    grant_type, code=payload.code, client_id=oauth_provider_app.client_id
                )
                return jsonable_encoder(
                    {
                        "access_token": access_token,
                        "token_type": "Bearer",
                        "expires_in": OAUTH_ACCESS_TOKEN_EXPIRES_IN,
                        "refresh_token": refresh_token,
                    }
                )

View on GitHub (pinned to ef8544b173)

Solutions

  1. First call POST /oauth/provider/authorize to obtain a code, then pass that exact code in the token request.
  2. Inspect the token request body to confirm the code field is populated and non-empty before sending.
  3. Handle the authorize-step response carefully so the code is not overwritten or dropped before the token call.
Defensive patterns

Strategy: validation

Validate before calling

if (grantType === 'authorization_code' && !code) {
  throw new Error('Obtain a code from /oauth/provider/authorize first');
}

Type guard

function hasCode(p: {code?: string}): boolean { return typeof p.code === 'string' && p.code.length > 0; }

Try / catch

try {
  await exchangeCodeForToken(code, clientId, clientSecret, redirectUri);
} catch (e) {
  if (/code is required/i.test(e.message)) { reRunAuthorize(); } else throw e;
}

Prevention

When it happens

Trigger: POST /oauth/provider/token with grant_type=authorization_code but the code field omitted or empty. Typically the client forgot to include the code returned by /oauth/provider/authorize, or the code variable was never populated.

Common situations: Client lost the authorization code between the authorize step and the token step (page reload, expired state), or wired the flow incorrectly and posts an empty code.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/b17fa978d32e4720. Report an issue: GitHub.