{"record":{"id":"3dee0e7720ea98ea","repo":"passbolt/passbolt_api","slug":"response-getreasonphrase-dynamic-provider-error-3dee0e","errorCode":null,"errorMessage":"$response->getReasonPhrase() (dynamic provider error)","messagePattern":"\\$response->getReasonPhrase\\(\\) \\(dynamic provider error\\)","errorType":"exception","errorClass":"IdentityProviderException","httpStatus":null,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Utility/OAuth2/Provider/OAuth2Provider.php","lineNumber":59,"sourceCode":"        $this->grantFactory->setGrant('jwt_bearer', new JwtBearer());\n    }\n\n    /**\n     * {@inheritDoc}\n     *\n     * @throws \\Passbolt\\Sso\\Error\\Exception\\OAuth2Exception When error and error description is present\n     * @throws \\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException When unknown error faced\n     */\n    protected function checkResponse(ResponseInterface $response, $data): void\n    {\n        if (empty($data['error'])) {\n            return;\n        }\n\n        if (is_string($data['error']) && isset($data['error_description']) && is_string($data['error_description'])) {\n            throw new OAuth2Exception($data['error'], $data['error_description']);\n        } else {\n            throw new IdentityProviderException(\n                $response->getReasonPhrase(),\n                $response->getStatusCode(),\n                (string)$response->getBody()\n            );\n        }\n    }\n\n    /**\n     * @inheritDoc\n     */\n    protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface\n    {\n        return new OAuth2ResourceOwner($response);\n    }\n}\n","sourceCodeStart":41,"sourceCodeEnd":75,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Utility/OAuth2/Provider/OAuth2Provider.php#L41-L75","documentation":"This is the fallback branch of OAuth2Provider::checkResponse: when the error response body is not in the standard `error`+`error_description` string shape, the library throws an IdentityProviderException built from the PSR-7 response's reason phrase (e.g. 'Bad Request', 'Internal Server Error'), status code, and raw body. It surfaces non-conformant or non-JSON provider error responses.","triggerScenarios":"checkResponse receives an error response (body containing `error`, or non-2xx) whose `error` field is not a string with a string `error_description` — e.g. HTML error pages, JSON with nested/numeric error values, or empty bodies from proxies.","commonSituations":"Provider outage returning HTML 502/503 pages through a load balancer; corporate proxy intercepting TLS and returning its own error page; provider API version change altering the error payload shape.","solutions":["Inspect the IdentityProviderException body/status to see the raw provider response and identify the true failure.","Check provider status pages and network path (proxies, load balancers) for intercepted or malformed responses.","Confirm the token endpoint URL in the SSO provider settings points at the correct, current OAuth2 endpoint.","Retry the flow once transient upstream outages (5xx reason phrases) are ruled out."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if ($response->getStatusCode() >= 400) {\n    // inspect reason phrase and body before parsing token data\n}","typeGuard":"function isConformantOAuthError(array $data): bool {\n    return is_string($data['error'] ?? null) && is_string($data['error_description'] ?? null);\n}","tryCatchPattern":"try {\n    $provider->checkResponse($response, $data);\n} catch (IdentityProviderException $e) {\n    // log $e->getBody()/status; check provider status page / proxy interference\n}","preventionTips":["Monitor provider status pages and alert on 5xx reason phrases","Exclude the token endpoint from TLS-intercepting proxies","Pin and review provider endpoint URLs after API version changes"],"tags":["oauth2","sso","http-response","identity-provider"],"backgroundTag":"upstream-api-error","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}