{"record":{"id":"9063a6f5e2152f63","repo":"DenverCoder1/github-readme-streak-stats","slug":"400-github-username-is-required","errorCode":"400","errorMessage":"GitHub username is required.","messagePattern":"GitHub username is required\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":400,"severity":"warning","filePath":"src/generator.php","lineNumber":16,"sourceCode":"<?php\n\ndeclare(strict_types=1);\n\n/**\n * Generate streak stats for a GitHub user from request-style parameters.\n *\n * @param string $user GitHub username to get stats for\n * @param array<string,mixed> $params Options that affect fetching and streak calculation\n * @return array<string,mixed> The calculated streak stats\n */\nfunction generateStreakStats(string $user, array $params = []): array\n{\n    $user = preg_replace(\"/[^a-zA-Z0-9\\-]/\", \"\", $user);\n    if ($user === \"\") {\n        throw new InvalidArgumentException(\"GitHub username is required.\", 400);\n    }\n\n    $startingYear = isset($params[\"starting_year\"]) ? intval($params[\"starting_year\"]) : null;\n    $mode = isset($params[\"mode\"]) ? strval($params[\"mode\"]) : null;\n    $excludeDaysRaw = isset($params[\"exclude_days\"]) ? strval($params[\"exclude_days\"]) : \"\";\n    $timezone = isset($params[\"timezone\"]) ? strval($params[\"timezone\"]) : \"\";\n\n    // Build cache options based on request parameters\n    $cacheOptions = [\n        \"starting_year\" => $startingYear,\n        \"mode\" => $mode,\n        \"exclude_days\" => $excludeDaysRaw,\n        \"timezone\" => $timezone,\n    ];\n\n    // Check if cache is disabled\n    $useCache = !isset($_SERVER[\"DISABLE_CACHE\"]) || strtolower(strval($_SERVER[\"DISABLE_CACHE\"])) !== \"true\";\n","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/DenverCoder1/github-readme-streak-stats/blob/70dd50f921097927dc8314ac33a04b010a09924d/src/generator.php#L1-L34","documentation":"generateStreakStats() requires a GitHub username. After stripping all characters except alphanumerics and hyphens, an empty string means no usable username was supplied, so it throws InvalidArgumentException with code 400.","triggerScenarios":"Calling generateStreakStats('', ...) or passing a user value made entirely of characters that get stripped (e.g. symbols or spaces).","commonSituations":"Missing 'user' query parameter in an HTTP integration; a client sending whitespace-only or encoded-special-character usernames.","solutions":["Pass a non-empty GitHub username as the $user argument","Validate the username client-side before calling","Ensure the query parameter name is correct so the value isn't empty","Use only characters valid for GitHub usernames (letters, digits, hyphens)"],"exampleFix":"// before\ngenerateStreakStats($_GET[\"user\"] ?? \"\");\n// after\n$user = $_GET[\"user\"] ?? \"\";\nif ($user === \"\") { http_response_code(400); exit(\"user required\"); }\ngenerateStreakStats($user);","handlingStrategy":"validation","validationCode":"if (!is_string($user) || preg_match('/^[a-zA-Z0-9-]{1,39}$/', $user) !== 1) { throw new InvalidArgumentException(\"username required\"); }","typeGuard":"function isValidGitHubUsername($u): bool { return is_string($u) && preg_match('/^[a-zA-Z0-9-]{1,39}$/', $u) === 1; }","tryCatchPattern":"try { $stats = generateStreakStats($user); } catch (InvalidArgumentException $e) { if ($e->getCode() === 400) { http_response_code(400); echo \"Username is required\"; } }","preventionTips":["Validate the user parameter at the HTTP boundary before calling library functions","Never pass raw/unsanitized query parameters","Check for empty strings after your own trimming/sanitization"],"tags":["php","validation","missing-argument"],"backgroundTag":"empty-required-field","analyzedSha":"70dd50f921097927dc8314ac33a04b010a09924d","analyzedAt":"2026-09-15T02:40:51.909Z","contentChangedAt":"2026-09-15T02:40:51.909Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}