{"record":{"id":"775664e10036fd45","repo":"yiisoft/yii2","slug":"password-must-be-a-string-and-cannot-be-empty","errorCode":null,"errorMessage":"Password must be a string and cannot be empty.","messagePattern":"Password must be a string and cannot be empty\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/base/Security.php","lineNumber":492,"sourceCode":"        if ($cost === null) {\n            $cost = $this->passwordHashCost;\n        }\n\n        return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);\n    }\n\n    /**\n     * Verifies a password against a hash.\n     * @param string $password The password to verify.\n     * @param string $hash The hash to verify the password against.\n     * @return bool whether the password is correct.\n     * @throws InvalidArgumentException on bad password/hash parameters.\n     * @see generatePasswordHash()\n     */\n    public function validatePassword($password, $hash)\n    {\n        if (!is_string($password) || $password === '') {\n            throw new InvalidArgumentException('Password must be a string and cannot be empty.');\n        }\n\n        if (\n            !preg_match('/^\\$2[axy]\\$(\\d\\d)\\$[\\.\\/0-9A-Za-z]{22}/', $hash, $matches)\n            || $matches[1] < 4\n            || $matches[1] > 30\n        ) {\n            throw new InvalidArgumentException('Hash is invalid.');\n        }\n\n        return password_verify($password, $hash);\n    }\n\n    /**\n     * Generates a salt that can be used to generate a password hash.\n     *\n     * The PHP [crypt()](https://www.php.net/manual/en/function.crypt.php) built-in function\n     * requires, for the Blowfish hash algorithm, a salt string in a specific format:","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/base/Security.php#L474-L510","documentation":"Security::validatePassword() verifies bcrypt hashes and first asserts that the password argument is a non-empty string; null, non-string values, or '' throw InvalidArgumentException before the hash format check and password_verify(). This is strictly about the password argument — a malformed $hash raises the separate 'Hash is invalid.' error instead.","triggerScenarios":"validatePassword(null, $hash) when the source attribute is nullable and null-coalesced incorrectly; an optional password field routed straight from request data with '' after trimming; array/scalar-mistyped input forwarded from a wrapper; test fixtures using empty strings.","commonSituations":"Login or token-verification endpoints that skip their own empty-input validation and call Security directly; nullable database columns feeding the call; API clients omitting the field so it decodes to null.","solutions":["Handle empty/missing passwords as a failed verification in the caller before invoking Security","Cast genuinely scalar input and bail on emptiness: $password = (string) $input; if ($password === '') return false;","Mark the password attribute required+string in your Model rules so bad input dies at form validation, not inside Security","For API input, reject non-string/empty password fields with a 4xx response at the boundary"],"exampleFix":"// before\n$ok = Yii::$app->security->validatePassword($model->password ?? null, $user->password_hash);\n// null password → InvalidArgumentException\n\n// after\n$password = $model->password ?? '';\n$ok = $password !== '' && Yii::$app->security->validatePassword($password, $user->password_hash);","handlingStrategy":"validation","validationCode":"if (!is_string($password) || $password === '') {\n    return false; // empty/missing password is a failed verification, not an exception\n}\nreturn Yii::$app->security->validatePassword($password, $hash);","typeGuard":"function isNonEmptyPassword($password): bool\n{\n    return is_string($password) && $password !== '';\n}","tryCatchPattern":"try {\n    $ok = Yii::$app->security->validatePassword($password, $hash);\n} catch (\\InvalidArgumentException $e) {\n    // empty/non-string password or invalid hash — treat as failed login and log the argument type, never the value\n    $ok = false;\n}","preventionTips":["Make the login form's password attribute required + string so bad input dies at model validation","Null-coalesce nullable attributes to '' and short-circuit before calling Security","Reject non-string or empty password fields with 4xx at API boundaries"],"tags":["php","yii2","security","password","bcrypt","argument-validation"],"backgroundTag":"empty-required-parameter","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}