{"record":{"id":"8ac5ef40fcfcdd84","repo":"thephpleague/oauth2-server","slug":"invalid-client-8ac5ef","errorCode":"invalid_client","errorMessage":"invalid_client","messagePattern":"invalid_client","errorType":"http","errorClass":"OAuthServerException","httpStatus":401,"severity":"error","filePath":"src/Grant/AuthCodeGrant.php","lineNumber":279,"sourceCode":"        );\n\n        if ($clientId === null) {\n            throw OAuthServerException::invalidRequest('client_id');\n        }\n\n        $client = $this->getClientEntityOrFail($clientId, $request);\n\n        $redirectUri = $this->getQueryStringParameter('redirect_uri', $request);\n\n        if ($redirectUri !== null) {\n            $this->validateRedirectUri($redirectUri, $client, $request);\n        } elseif (\n            $client->getRedirectUri() === '' ||\n            (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1)\n        ) {\n            $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));\n\n            throw OAuthServerException::invalidClient($request);\n        }\n\n        $stateParameter = $this->getQueryStringParameter('state', $request);\n\n        $scopes = $this->validateScopes(\n            $this->getQueryStringParameter('scope', $request, $this->defaultScope),\n            $this->makeRedirectUri(\n                $redirectUri ?? $this->getClientRedirectUri($client),\n                $stateParameter !== null ? ['state' => $stateParameter] : []\n            )\n        );\n\n        $authorizationRequest = $this->createAuthorizationRequest();\n        $authorizationRequest->setGrantTypeId($this->getIdentifier());\n        $authorizationRequest->setClient($client);\n        $authorizationRequest->setRedirectUri($redirectUri);\n\n        if ($stateParameter !== null) {","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/thephpleague/oauth2-server/blob/9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c/src/Grant/AuthCodeGrant.php#L261-L297","documentation":"invalid_client: the client was found but its registered redirect URI is empty, or it is an array with a count other than exactly 1. The auth code grant requires exactly one usable redirect URI, and a CLIENT_AUTHENTICATION_FAILED event is emitted before throwing.","triggerScenarios":"validateAuthorizationRequest() reaches the branch where $client->getRedirectUri() === '' or is_array($client->getRedirectUri()) && count(...) !== 1 — i.e. the client entity returned by your ClientRepository has a blank or multi-value (non-single) redirect URI.","commonSituations":"Custom ClientRepository returning a client entity with redirectUri left as an empty string or an array of several URIs; misconfigured client record in the database; implementing ClientEntityInterface without normalizing the redirect URI.","solutions":["Fix the client's stored redirect URI to a single non-empty string","If your entity supports multiple redirect URIs, return exactly one where this grant requires it, or return a single string","Update your ClientRepository/entity mapping so the redirect_uri column is not empty/null","Re-check client seeding/migration scripts for blank redirect_uri values"],"exampleFix":"// before (client entity)\n$this->redirectUri = []; // or ''\n// after\n$this->redirectUri = 'https://app.example.com/callback';","handlingStrategy":"type-guard","validationCode":"// in your ClientRepository::getClientEntity()\n$redirectUri = $clientRecord['redirect_uri'] ?? '';\nif (!is_string($redirectUri) || $redirectUri === '') {\n    throw new \\RuntimeException('Client must have exactly one registered redirect URI');\n}","typeGuard":"function hasUsableRedirectUri($redirectUri): bool {\n    if (is_array($redirectUri)) {\n        return count($redirectUri) === 1;\n    }\n    return is_string($redirectUri) && $redirectUri !== '';\n}","tryCatchPattern":"try {\n    $authRequest = $server->validateAuthorizationRequest($request);\n} catch (OAuthServerException $e) {\n    if ($e->getErrorType() === 'invalid_client') {\n        // fix the client record: redirect URI empty or multi-value array\n    }\n}","preventionTips":["Validate client records (non-empty, single redirect URI) at seed/migration time","Listen for the CLIENT_AUTHENTICATION_FAILED event to log misconfigurations early","Implement ClientEntityInterface getters defensively"],"tags":["oauth2","invalid-client","redirect-uri","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c","analyzedAt":"2026-09-15T22:33:30.452Z","contentChangedAt":"2026-09-15T22:33:30.452Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}