{"record":{"id":"bd2227c26fffebdf","repo":"thephpleague/oauth2-server","slug":"server-error-an-unexpected-has-occurred","errorCode":"server_error","errorMessage":"An unexpected error has occurred","messagePattern":"An unexpected error has occurred","errorType":"http","errorClass":"OAuthServerException","httpStatus":500,"severity":"critical","filePath":"src/Grant/DeviceCodeGrant.php","lineNumber":312,"sourceCode":"    /**\n     * Generate a new user code.\n     *\n     * @throws OAuthServerException\n     */\n    protected function generateUserCode(int $length = 8): string\n    {\n        try {\n            $userCode = '';\n            $userCodeCharacters = 'BCDFGHJKLMNPQRSTVWXZ';\n\n            while (strlen($userCode) < $length) {\n                $userCode .= $userCodeCharacters[random_int(0, 19)];\n            }\n\n            return $userCode;\n            // @codeCoverageIgnoreStart\n        } catch (TypeError | Error $e) {\n            throw OAuthServerException::serverError('An unexpected error has occurred', $e);\n        } catch (Exception $e) {\n            // If you get this message, the CSPRNG failed hard.\n            throw OAuthServerException::serverError('Could not generate a random string', $e);\n        }\n        // @codeCoverageIgnoreEnd\n    }\n\n    public function setIntervalVisibility(bool $intervalVisibility): void\n    {\n        $this->intervalVisibility = $intervalVisibility;\n    }\n\n    public function getIntervalVisibility(): bool\n    {\n        return $this->intervalVisibility;\n    }\n\n    public function setIncludeVerificationUriComplete(bool $includeVerificationUriComplete): void","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/thephpleague/oauth2-server/blob/9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c/src/Grant/DeviceCodeGrant.php#L294-L330","documentation":"A generic 500-level server_error wrapped as OAuthServerException::serverError('An unexpected error has occurred', $e). In DeviceCodeGrant::generateUserCode it catches TypeError or Error from random_int() / string generation and rethrows as this opaque server error. It indicates an unexpected engine-level failure while building the user code, not a client mistake.","triggerScenarios":"issueDeviceCode -> generateUserCode when random_int(0, 19) or the surrounding user-code loop throws TypeError or Error - e.g. invalid charset string passed as the user code alphabet, or a PHP engine/CSPRNG fault.","commonSituations":"Custom user code character set configured incorrectly (e.g. non-string multibyte value); PHP without a working random source in a hardened container; running an unsupported PHP version where random_int is unavailable.","solutions":["Check the PHP error log for the wrapped previous exception ($e) to find the real cause","Verify setUserDataCharacterSet (or equivalent) was given a valid non-empty string of single-byte characters","Ensure the runtime provides a working CSPRNG (php -r \"var_dump(function_exists('random_int'));\" and /dev/urandom availability)","Upgrade the library and PHP to supported versions"],"exampleFix":"// before\n$grant->setUserDataCharacterSet('ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜ'); // multibyte chars can break byte-based generation\n// after\n$grant->setUserDataCharacterSet(DeviceCodeGrant::DEFAULT_USER_CODE_CHARACTERS); // BCDFGHJKLMNPQRSTVWXZ","handlingStrategy":"try-catch","validationCode":"if (!function_exists('random_int') || !is_string($userCodeCharacters)) {\n    throw new \\RuntimeException('CSPRNG unavailable or invalid user code character set');\n}","typeGuard":"function isValidUserCharacterSet(?string $chars): bool {\n    return $chars !== null && $chars !== '' && strlen($chars) === mb_strlen($chars);\n}","tryCatchPattern":"try {\n    $grant->issueDeviceCode($client, $user, $scopes, $interval, $verifyUri);\n} catch (OAuthServerException $e) {\n    if ($e->getErrorType() === 'server_error') {\n        error_log('Device code generation failed: ' . $e->getPrevious());\n    }\n    throw $e;\n}","preventionTips":["Use only single-byte ASCII characters in the user code character set","Run PHP versions where random_int is stable and entropy is available","Log the previous exception for server_error responses to find root causes"],"tags":["oauth2","server-error","randomness","php"],"backgroundTag":"internal-invariant-violation","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"}