getgrav/grav · error · InvalidArgumentException
Uri path must be a string
Error message
Uri path must be a string
What it means
UriPartsFilter::filterPath() percent-encodes reserved characters in a URI path (without double-encoding existing sequences) and first asserts the input is a string, throwing InvalidArgumentException otherwise. It backs AbstractUri::withPath(), the Uri parts constructor, and Grav\Common\Uri's path helper. Since withPath() declares a native string parameter, the throw mainly fires via direct filterPath() calls or untyped call sites receiving null/array.
Source
Thrown at system/src/Grav/Framework/Uri/UriPartsFilter.php:110
throw new InvalidArgumentException('Uri port must be null or an integer between 0 and 65535');
}
/**
* Filter Uri path.
*
* This method percent-encodes all reserved characters in the provided path string. This method
* will NOT double-encode characters that are already percent-encoded.
*
* @param string $path The raw uri path.
* @return string The RFC 3986 percent-encoded uri path.
* @throws InvalidArgumentException If the path is invalid.
* @link http://www.faqs.org/rfcs/rfc3986.html
*/
public static function filterPath($path)
{
if (!is_string($path)) {
throw new InvalidArgumentException('Uri path must be a string');
}
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)
{View on GitHub (pinned to 6040efed04)
Solutions
- Default to an empty path: `$path = $segments[0] ?? ''`
- Cast scalars and reject arrays before building URIs
- Prefer the typed `$uri->withPath($path)` boundary
Example fix
// before $path = UriPartsFilter::filterPath($route['path'] ?? null); // null -> throws // after $path = UriPartsFilter::filterPath((string) ($route['path'] ?? ''));
Defensive patterns
Strategy: type-guard
Validate before calling
$path = $route['path'] ?? '';
if (!is_string($path)) {
throw new \InvalidArgumentException('path must be a string');
} Type guard
function isPathString(mixed $value): bool
{
return is_string($value);
} Prevention
- Default optional path segments to '' instead of null
- Check array_shift()/optional lookups for null before feeding results to URI builders
- Use the typed withPath() API
When it happens
Trigger: Calling filterPath(null) when a route/segment lookup returned null; passing an array produced by a path-explode operation; feeding an object (e.g. Stringable) without casting on direct calls.
Common situations: Route builders where an optional path segment config is absent; array_shift() on an already-exhausted segments array yielding null that then flows into the filter.
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/c7c46b9ce87750c1.
Report an issue: GitHub.