symfony/symfony · error · LogicException

The request was not redirected.

Error message

The request was not redirected.

What it means

Thrown by AbstractBrowser::followRedirect() (line 551) when called but the most recent request did not produce a redirect - i.e. $this->redirect was never set (the response status was not 3xx without a Location header, or followRedirects was off and the property stayed null). The contract is: you can only followRedirect() after a request that actually redirected.

Source

Thrown at src/Symfony/Component/BrowserKit/AbstractBrowser.php:551

    }

    /**
     * Reloads the current browser.
     */
    public function reload(): Crawler
    {
        return $this->requestFromRequest($this->history->current(), false);
    }

    /**
     * Follow redirects?
     *
     * @throws LogicException If request was not a redirect
     */
    public function followRedirect(): Crawler
    {
        if (!isset($this->redirect)) {
            throw new LogicException('The request was not redirected.');
        }

        if (-1 !== $this->maxRedirects) {
            if ($this->redirectCount > $this->maxRedirects) {
                $this->redirectCount = 0;
                throw new LogicException(\sprintf('The maximum number (%d) of redirections was reached.', $this->maxRedirects));
            }
        }

        $request = $this->internalRequest;

        if (\in_array($this->internalResponse->getStatusCode(), [301, 302, 303], true)) {
            $method = 'GET';
            $files = [];
            $content = null;
        } else {
            $method = $request->getMethod();
            $files = $request->getFiles();

View on GitHub (pinned to 698e28026c)

Solutions

  1. Check the response status before following: `if ($client->getInternalResponse()->getStatusCode() >= 300 && < 400) { $client->followRedirect(); }`.
  2. Inspect `$client->getInternalResponse()->getHeader('Location')` to confirm a redirect exists.
  3. If using `followRedirects(false)`, only call followRedirect() after verifying a 3xx response.
  4. Avoid calling followRedirect() after auto-following has already consumed the redirect.

Example fix

// before
$client->followRedirects(false);
$client->request('GET', '/maybe-redirect');
$client->followRedirect(); // may throw if not a redirect

// after
$client->followRedirects(false);
$client->request('GET', '/maybe-redirect');
if (in_array($client->getInternalResponse()->getStatusCode(), [301,302,303,307,308], true)) {
    $client->followRedirect();
}
Defensive patterns

Strategy: validation

Validate before calling

$client->followRedirects(false);
$client->request('GET', '/maybe-redirect');
$status = $client->getInternalResponse()->getStatusCode();
if ($status >= 300 && $status < 400 && null !== $client->getInternalResponse()->getHeader('Location')) {
    $client->followRedirect();
}

Type guard

function clientHasPendingRedirect(\Symfony\Component\BrowserKit\AbstractBrowser $c): bool {
    $r = new \ReflectionObject($c);
    $prop = $r->getProperty('redirect');
    if (!$prop->isInitialized($c)) {
        return false;
    }
    return null !== $prop->getValue($c);
}

Try / catch

try {
    $client->followRedirect();
} catch (\Symfony\Component\BrowserKit\Exception\LogicException $e) {
    if (str_contains($e->getMessage(), 'was not redirected')) {
        // not a redirect; assert on the actual response
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling `$client->followRedirect()` manually after a request that returned a 2xx response; calling it twice (the second time the redirect has already been consumed); calling it when followRedirects was off and the previous response had no Location header.

Common situations: Tests that assume a route redirects but it returns 200; calling followRedirect() after the client already auto-followed; misordered assertions where followRedirect runs against a non-redirect response; redirects disabled via `$client->followRedirects(false)` then forgetting to check the status.

Related errors


AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06). Data as JSON: /api/errors/b1f9c9dc1d5af70d. Report an issue: GitHub.