getgrav/grav · error · InvalidArgumentException
Uri user info must be a string
Error message
Uri user info must be a string
What it means
UriPartsFilter::filterUserInfo() percent-encodes the user/password component and asserts the input is a string, throwing InvalidArgumentException otherwise. It backs AbstractUri::withUserInfo() and Grav\Common\Uri's user-info helper (which already null-guards). Because withUserInfo() declares native string parameters, this exception effectively fires only on direct filterUserInfo() calls with a non-string, non-null value.
Source
Thrown at system/src/Grav/Framework/Uri/UriPartsFilter.php:48
{
if (!is_string($scheme)) {
throw new InvalidArgumentException('Uri scheme must be a string');
}
return strtolower($scheme);
}
/**
* Filters the user info string.
*
* @param string $info The raw user or password.
* @return string The percent-encoded user or password string.
* @throws InvalidArgumentException
*/
public static function filterUserInfo($info)
{
if (!is_string($info)) {
throw new InvalidArgumentException('Uri user info must be a string');
}
return preg_replace_callback(
'/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u',
fn($match) => rawurlencode((string) $match[0]),
$info
) ?? '';
}
/**
* @param string $host
* @return string
* @throws InvalidArgumentException If the host is invalid.
*/
public static function filterHost($host)
{
if (!is_string($host)) {
throw new InvalidArgumentException('Uri host must be a string');View on GitHub (pinned to 6040efed04)
Solutions
- Pass the string form: `(string) $username` after confirming it is scalar
- Use the typed `$uri->withUserInfo($user, $pass)` API, which coerces earlier and fails with a clearer TypeError
- Null-check before calling if the field is optional
Example fix
// before $user = UriPartsFilter::filterUserInfo($row['user_id']); // int 42 -> throws // after $user = UriPartsFilter::filterUserInfo((string) $row['username']);
Defensive patterns
Strategy: type-guard
Validate before calling
$user = is_scalar($authUser) ? (string) $authUser : '';
Type guard
function isUserInfoString(mixed $value): bool
{
return is_string($value);
} Prevention
- Cast database ids to their string form before using them as URI userinfo
- Use the typed withUserInfo() boundary so failures surface as clear TypeErrors
- Null-check optional userinfo before filtering
When it happens
Trigger: Calling UriPartsFilter::filterUserInfo() directly with an int/array (e.g. user id from a database instead of the username string); userinfo extracted from a hand-parsed URL where the user segment was captured as an array by a greedy regex.
Common situations: Proxy/auth middleware building a URI from database or header fields where a numeric user id or array sneaks into the username slot.
Related errors
- URL must be a string
- Uri scheme must be a string
- Uri host must be a string
- Uri port must be null or an integer between 0 and 65535
- Uri path must be a string
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/66426eaa8ec50190.
Report an issue: GitHub.