thephpleague/oauth2-server · error · OAuthServerException

invalid_request

invalid_request

Error message

The request is missing a required parameter, is invalid, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "code" parameter

What it means

Thrown by the authorization code grant's respondToAccessTokenRequest when the token request has no 'code' parameter to exchange. The grant validates the client, then reads the required 'code' request parameter; its absence makes the token exchange request invalid under the OAuth2 spec.

Solutions

  1. Ensure the token request includes the code parameter received from the authorization redirect: POST code=<authorization_code> with grant_type=authorization_code
  2. Verify your HTTP layer forwards the authorization response's ?code=... query value to the token request body
  3. Check parameter naming — it must be exactly 'code', not 'auth_code' or 'authorization_code'
  4. In tests, add 'code' to the request body before calling respondToAccessTokenRequest

Example fix

// before
const body = { grant_type: 'authorization_code', client_id, redirect_uri };
// after
const body = { grant_type: 'authorization_code', client_id, redirect_uri, code: authCode };
Defensive patterns

Strategy: validation

Validate before calling

if (!authCode || typeof authCode !== 'string') {
  throw new Error('authorization code missing — cannot call token endpoint');
}

Type guard

function hasAuthCode(q: Record<string, unknown>): q is Record<string, string> & { code: string } { return typeof q.code === 'string' && q.code.length > 0; }

Try / catch

try {
  return await tokenClient.exchange({ grant_type: 'authorization_code', code, ... });
} catch (e) {
  if (e.code === 'invalid_request' && e.hint?.includes('code')) {
    console.error('Token request missing code parameter');
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing to /access_token with grant_type=authorization_code but omitting the code parameter, sending it under a different key (e.g. authorization_code or authCode), or the client losing the code between the redirect and the token call.

Common situations: Client-side redirect handlers store the code in state but never include it in the token request; frontend/backend mismatches where the frontend strips query params; single-page apps calling the token endpoint with only code_verifier and client_id; integration tests whose POST body lacks 'code'.

Understand the failure class

Related errors


AI-assisted analysis of thephpleague/oauth2-server@9d2f6fc0a0 (2026-09-15). Data as JSON: /api/errors/7144e1f22bcb9f70. Report an issue: GitHub.

Appendix: source

Thrown at src/Grant/AuthCodeGrant.php:105

        $this->requireCodeChallengeForPublicClients = false;
    }

    /**
     * Respond to an access token request.
     *
     * @throws OAuthServerException
     */
    public function respondToAccessTokenRequest(
        ServerRequestInterface $request,
        ResponseTypeInterface $responseType,
        DateInterval $accessTokenTTL
    ): ResponseTypeInterface {
        $client = $this->validateClient($request);

        $encryptedAuthCode = $this->getRequestParameter('code', $request);

        if ($encryptedAuthCode === null) {
            throw OAuthServerException::invalidRequest('code');
        }

        try {
            $authCodePayload = json_decode($this->decrypt($encryptedAuthCode));

            $this->validateAuthorizationCode($authCodePayload, $client, $request);

            $scopes = $this->scopeRepository->finalizeScopes(
                $this->validateScopes($authCodePayload->scopes),
                $this->getIdentifier(),
                $client,
                $authCodePayload->user_id,
                $authCodePayload->auth_code_id
            );
        } catch (InvalidArgumentException $e) {
            throw OAuthServerException::invalidGrant('Cannot validate the provided authorization code');
        } catch (LogicException $e) {
            throw OAuthServerException::invalidRequest('code', 'Issue decrypting the authorization code', $e);

View on GitHub (pinned to 9d2f6fc0a0)