{"record":{"id":"0136140351cd819d","repo":"symfony/routing","slug":"parameters-for-route-s-cannot-contain-a-circular-reference","errorCode":null,"errorMessage":"Parameters for route \"%s\" cannot contain a circular reference (in object of class \"%s\").","messagePattern":"Parameters for route \"(.+?)\" cannot contain a circular reference \\(in object of class \"(.+?)\"\\)\\.","errorType":"validation","errorClass":"InvalidParameterException","httpStatus":null,"severity":"error","filePath":"Generator/UrlGenerator.php","lineNumber":292,"sourceCode":"                $schemeAuthority .= $host.$port;\n            }\n        }\n\n        if (self::RELATIVE_PATH === $referenceType) {\n            $url = self::getRelativePath($this->context->getPathInfo(), $url);\n        } else {\n            $url = $schemeAuthority.$this->context->getBaseUrl().$url;\n        }\n\n        // add a query string if needed\n        $extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, static fn ($a, $b) => $a == $b ? 0 : 1);\n        $extra = array_replace($defaultQuery, $extra, $queryParameters);\n\n        $seen = [];\n        array_walk_recursive($extra, $caster = static function (&$v) use (&$caster, &$seen, $name) {\n            if (\\is_object($v)) {\n                if (isset($seen[$id = spl_object_id($v)])) {\n                    throw new InvalidParameterException(\\sprintf('Parameters for route \"%s\" cannot contain a circular reference (in object of class \"%s\").', $name, get_debug_type($v)));\n                }\n                if ($vars = get_object_vars($v)) {\n                    $seen[$id] = true;\n                    array_walk_recursive($vars, $caster);\n                    unset($seen[$id]);\n                    $v = $vars;\n                } elseif ($v instanceof \\Stringable) {\n                    $v = (string) $v;\n                } else {\n                    $v = [];\n                }\n            }\n        });\n\n        // extract fragment\n        $fragment = $defaults['_fragment'] ?? '';\n\n        if (isset($extra['_fragment'])) {","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Generator/UrlGenerator.php#L274-L310","documentation":"When serializing extra query parameters into the generated URL string, UrlGenerator casts nested objects to arrays using get_object_vars. If the same object appears twice (a circular reference / repeated object), an infinite recursion would occur, so InvalidParameterException is thrown naming the object's class.","triggerScenarios":"Passing a query parameter that references an object already passed (e.g. ['obj' => $o, 'nested' => ['o' => $o]]) or an object whose property graph is self-referential, when calling generate().","commonSituations":"Passing Doctrine entities with back-references (bidirectional relations) or models holding a parent pointer into generate()'s query array.","solutions":["Remove the circularly-referencing object from the parameters or clone the parts you need.","Cast parameters to scalars/arrays explicitly before passing them (e.g. ->toArray() on the entity or DTO).","Use an ID instead of the object reference in the query parameters."],"exampleFix":"// before\n$router->generate('list', ['q' => $entity]); // entity has circular relation\n// after\n$router->generate('list', ['q' => $entity->getId()]);","handlingStrategy":"type-guard","validationCode":"function hasCircular(array $params): bool {\n  $seen = [];\n  array_walk_recursive($params, function ($v) use (&$seen, &$has) { if (is_object($v)) { $id = spl_object_id($v); if (isset($seen[$id])) { $has = true; } $seen[$id] = true; } });\n  return $has ?? false;\n}","typeGuard":"function allScalars(array $params): bool {\n  $ok = true;\n  array_walk_recursive($params, function ($v) use (&$ok) { if (!is_scalar($v) && null !== $v) { $ok = false; } });\n  return $ok;\n}","tryCatchPattern":"try { $url = $router->generate($name, $params); } catch (\\Symfony\\Component\\Routing\\Exception\\InvalidParameterException $e) { $url = $router->generate($name, array_map('strval', $scalarParams)); }","preventionTips":["Only pass scalars/null/flat arrays as query parameters.","Convert entities/DTOs with ->toArray() or explicit field extraction before generate().","Avoid passing objects with bidirectional relations into URL generation."],"tags":["symfony","routing","url-generation"],"backgroundTag":"invalid-argument-value","analyzedSha":"83fa223250b50f4f018c011e101c330e65ac63cc","analyzedAt":"2026-09-14T03:19:46.280Z","contentChangedAt":"2026-09-14T03:19:46.280Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}