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
- First call POST /oauth/provider/authorize to obtain a code, then pass that exact code in the token request.
- Inspect the token request body to confirm the code field is populated and non-empty before sending.
- 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
- Always call authorize before token; pass the returned code unchanged.
- Do not log or truncate the code in transit.
- Validate the code field is non-empty before posting.
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
- invalid grant_type
- refresh_token is required
- invalid_email
- redirect_uri is invalid
- client_secret is invalid
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/b17fa978d32e4720.
Report an issue: GitHub.