getgrav/grav · error · InvalidArgumentException
Uri query string and fragment must be a string
Error message
Uri query string and fragment must be a string
What it means
UriPartsFilter::filterQueryOrFragment() percent-encodes a query string or fragment and asserts the input is a string, throwing InvalidArgumentException otherwise. One filter serves both withQuery() and withFragment() as well as Grav\Common\Uri's query helper. As with the other filters, the native string parameters on the with*() methods mean this throw appears chiefly on direct calls passing null/array values.
Source
Thrown at system/src/Grav/Framework/Uri/UriPartsFilter.php:130
return preg_replace_callback(
'/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u',
fn($match) => rawurlencode((string) $match[0]),
$path
) ?? '';
}
/**
* Filters the query string or fragment of a URI.
*
* @param string $query The raw uri query string.
* @return string The percent-encoded query string.
* @throws InvalidArgumentException If the query is invalid.
*/
public static function filterQueryOrFragment($query)
{
if (!is_string($query)) {
throw new InvalidArgumentException('Uri query string and fragment must be a string');
}
return preg_replace_callback(
'/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u',
fn($match) => rawurlencode((string) $match[0]),
$query
) ?? '';
}
}
View on GitHub (pinned to 6040efed04)
Solutions
- Validate the raw parameter: `is_string($q) ? ... : ''`
- Build query strings with http_build_query() from arrays rather than filtering raw input
- Use the typed `$uri->withQuery($query)` / `withFragment($fragment)` APIs
Example fix
// before $query = UriPartsFilter::filterQueryOrFragment($_GET['q']); // ?q[]=x -> array -> throws // after $raw = $_GET['q'] ?? ''; $query = UriPartsFilter::filterQueryOrFragment(is_string($raw) ? $raw : '');
Defensive patterns
Strategy: type-guard
Validate before calling
$query = $_GET['q'] ?? '';
if (!is_string($query)) {
$query = ''; // or reject: array syntax (?q[]=) must not reach the filter
} Type guard
function isQueryStringString(mixed $value): bool
{
return is_string($value);
} Prevention
- Reject array syntax parameters at the request boundary for fields used as query strings
- Build queries from arrays with http_build_query() instead of filtering raw input
- Use the typed withQuery()/withFragment() APIs
When it happens
Trigger: Calling filterQueryOrFragment() directly with `$_GET['q']` when the client sent `?q[]=1` (array); passing null from an optional fragment; feeding an http_build_query() result that was overwritten by an array variable.
Common situations: Search/query parameters consumed without type validation; array-parameter injection (`?x[]=`) reaching code that filters the raw value.
Related errors
- URL must be a string
- Uri scheme must be a string
- Uri user info must be a string
- Uri host must be a string
- Uri port must be null or an integer between 0 and 65535
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/04303a219a17419b.
Report an issue: GitHub.