symfony/http-kernel · error · InvalidArgumentException
Passing non-scalar values as part of URI attributes to the…
Error message
Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is not supported. Use a different rendering strategy or pass scalar values.
What it means
AbstractSurrogateFragmentRenderer falls back to the inline strategy when the request has no ESI/SSI capability. ControllerReference attributes must be embedded in a URI in that path, which only works for scalars; non-scalar attributes trigger an InvalidArgumentException.
Solutions
- Ensure the surrogate is configured and the request has surrogate capability (Request::setTrustedProxies + ESI listener) so URIs are generated natively.
- Pass only scalar attribute values, or serialize complex data (e.g. json_encode) into a scalar attribute.
- Use a renderer that supports non-scalar attributes, such as the inline fragment renderer directly.
Example fix
// before
$renderer->render(new ControllerReference('App::foo', [], ['filters' => ['a','b']]), $request);
// after
$renderer->render(new ControllerReference('App::foo', [], ['filters' => 'a,b']), $request); Defensive patterns
Strategy: type-guard
Validate before calling
function hasNonScalars(array $attrs): bool {
foreach ($attrs as $v) { if (!is_scalar($v) && $v !== null) return true; }
return false;
}
if (hasNonScalars($ref->attributes) && !$surrogate->hasSurrogateCapability($request)) { /* flatten or skip */ } Type guard
$allScalar = fn(array $a): bool => array_reduce($a, fn($c,$v) => $c && (is_scalar($v) || $v === null), true);
Try / catch
try { $resp = $renderer->render($uri, $request); } catch (\InvalidArgumentException $e) { $resp = $inlineRenderer->render($uri, $request); } Prevention
- Keep fragment attributes scalar-only (strings, ints, bools)
- Serialize complex data before attaching to a ControllerReference
- Verify surrogate capability in the environment where fragments render
When it happens
Trigger: Calling render() with a ControllerReference whose $attributes array contains arrays/objects (e.g. ['filters' => ['a','b']]) on a request without surrogate capability, causing the inline fallback path.
Common situations: Rendering ESI/SSI fragments without an ESI/SSI-capable request (no surrogate capability headers in tests); passing nested arrays or objects as fragment attributes expecting object passing like hinclude/inline.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Error when rendering
- Unable to process an ESI tag without a "src" attribute.
- Unable to process an SSI tag without a "virtual" attribute.
- Request payload contains invalid "form" data.
- Unsupported format: " ".
AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13).
Data as JSON: /api/errors/0cebfdeb8e394600.
Report an issue: GitHub.
Appendix: source
Thrown at Fragment/AbstractSurrogateFragmentRenderer.php:61
*
* Additional available options:
*
* * alt: an alternative URI to render in case of an error
* * comment: a comment to add when returning the surrogate tag
* * absolute_uri: whether to generate an absolute URI or not. Default is false
*
* Note, that not all surrogate strategies support all options. For now
* 'alt' and 'comment' are only supported by ESI.
*
* @see Symfony\Component\HttpKernel\HttpCache\SurrogateInterface
*/
public function render(string|ControllerReference $uri, Request $request, array $options = []): Response
{
if (!$this->surrogate || !$this->surrogate->hasSurrogateCapability($request)) {
$request->attributes->set('_check_controller_is_allowed', true);
if ($uri instanceof ControllerReference && $this->containsNonScalars($uri->attributes)) {
throw new \InvalidArgumentException('Passing non-scalar values as part of URI attributes to the ESI and SSI rendering strategies is not supported. Use a different rendering strategy or pass scalar values.');
}
return $this->inlineStrategy->render($uri, $request, $options);
}
$absolute = $options['absolute_uri'] ?? false;
if ($uri instanceof ControllerReference) {
$uri = $this->generateSignedFragmentUri($uri, $request, $absolute);
}
$alt = $options['alt'] ?? null;
if ($alt instanceof ControllerReference) {
$alt = $this->generateSignedFragmentUri($alt, $request, $absolute);
}
$tag = $this->surrogate->renderIncludeTag($uri, $alt, $options['ignore_errors'] ?? false, $options['comment'] ?? '');
View on GitHub (pinned to aa3a39d728)