w7corp/easywechat · error · LogicException

You cannot use the "Symfony\Component\HttpClient\HttplugClie

Error message

You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".

What it means

The discovery fallback of Response::toPsrResponse(): php-http/discovery exists, but Psr17FactoryDiscovery::findResponseFactory()/findStreamFactory() throws NotFoundException because no PSR-17 implementation package (nyholm/psr7, guzzlehttp/psr7, ...) is installed for it to find. The NotFoundException is rethrown as this LogicException (worded for the HttplugClient) with the original chained as previous.

Source

Thrown at src/Kernel/HttpClient/Response.php:163

    }

    public function toPsrResponse(?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null): \Psr\Http\Message\ResponseInterface
    {
        $streamFactory ??= $responseFactory instanceof StreamFactoryInterface ? $responseFactory : null;

        if ($responseFactory === null || $streamFactory === null) {
            if (! class_exists(Psr17Factory::class) && ! class_exists(Psr17FactoryDiscovery::class)) {
                throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".');
            }

            try {
                $psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory : null;
                $responseFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); /** @phpstan-ignore-line */
                $streamFactory ??= $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); /** @phpstan-ignore-line */

                /** @phpstan-ignore-next-line */
            } catch (NotFoundException $e) {
                throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e);
            }
        }

        $psrResponse = $responseFactory->createResponse($this->getStatusCode());

        foreach ($this->getHeaders(false) as $name => $values) {
            foreach ($values as $value) {
                $psrResponse = $psrResponse->withAddedHeader($name, $value);
            }
        }

        $body = $this->response instanceof StreamableInterface ? $this->toStream(false) : StreamWrapper::createResource($this->response);
        $body = $streamFactory->createStreamFromResource($body);

        if ($body->isSeekable()) {
            $body->seek(0);
        }

View on GitHub (pinned to f0cf0a8b83)

Solutions

  1. composer require nyholm/psr7 (or guzzlehttp/psr7) to give discovery an implementation to find
  2. Or bypass discovery entirely by passing ResponseFactoryInterface and StreamFactoryInterface to toPsrResponse()
  3. Run composer dump-autoload / clear caches after changing PSR-7 packages so discovery picks them up
Defensive patterns

Strategy: validation

Validate before calling

// Ensure an implementation exists for discovery before calling
$hasPsr17 = class_exists(\Nyholm\Psr7\Factory\Psr17Factory::class)
    || class_exists(\GuzzleHttp\Psr7\HttpFactory::class);
if (! $hasPsr17) {
    throw new LogicException('No PSR-17 implementation installed; run: composer require nyholm/psr7');
}
$psr7 = $response->toPsrResponse();

Try / catch

try {
    $psr7 = $response->toPsrResponse();
} catch (\LogicException $e) {
    if (str_contains($e->getMessage(), 'PSR-17')) {
        // fall back to the wrapper API instead of a PSR-7 conversion
        $data = $response->toArray();
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling toPsrResponse() with no factory arguments when php-http/discovery is present but every concrete PSR-17 implementation has been removed or was never installed.

Common situations: composer require php-http/discovery without an implementation, dependency pruning in optimized builds, conflicting discovery caches after package changes.

Related errors


AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21). Data as JSON: /api/errors/682d42ae54973553. Report an issue: GitHub.