cakephp/cakephp · error · Cake\Core\Exception\CakeException

You must install paragonie/csp-builder to use CspMiddleware

Error message

You must install paragonie/csp-builder to use CspMiddleware

What it means

CspMiddleware depends on the optional paragonie/csp-builder package. At construction time it checks class_exists(CSPBuilder::class); if the package is not installed, it throws immediately because the middleware cannot function without it. The constructor type-hints CSPBuilder|array, but a plain array argument still requires the library to build the policy.

Solutions

  1. Run `composer require paragonie/csp-builder`
  2. Verify vendor/paragonie/csp-builder exists on the deployed host and the autoloader was regenerated (composer dump-autoload)
  3. If you only need static CSP headers, set them manually via SecurityHeadersMiddleware instead of CspMiddleware

Example fix

// before
$middleware->add(new CspMiddleware(['default-src' => ['self']]));
// after (first run)
// composer require paragonie/csp-builder
$middleware->add(new CspMiddleware(['default-src' => ['self']]));
Defensive patterns

Strategy: fallback

Validate before calling

if (!class_exists(\ParagonIE\CSPBuilder\CSPBuilder::class)) {
    // skip or install
}

Type guard

function isCspBuilderInstalled(): bool { return class_exists(\ParagonIE\CSPBuilder\CSPBuilder::class); }

Try / catch

try {
    $middleware->add(new CspMiddleware($config));
} catch (\Cake\Core\Exception\CakeException $e) {
    // fall back to manual header middleware or surface install instructions
}

Prevention

When it happens

Trigger: Adding CspMiddleware to middleware stack without running `composer require paragonie/csp-builder`; installing the package only in dev while deploying to production; autoloader not regenerated after composer install.

Common situations: Copy-pasting middleware config from docs without installing the optional dependency; composer.json missing the package in production builds; deploying via git without vendor/ and running composer with --no-dev where the package was only in require-dev.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/52c12e25070a57e2. Report an issue: GitHub.

Appendix: source

Thrown at src/Http/Middleware/CspMiddleware.php:66

     * Configuration options.
     *
     * @var array<string, mixed>
     */
    protected array $_defaultConfig = [
        'scriptNonce' => false,
        'styleNonce' => false,
    ];

    /**
     * Constructor
     *
     * @param \ParagonIE\CSPBuilder\CSPBuilder|array $csp CSP object or config array
     * @param array<string, mixed> $config Configuration options.
     */
    public function __construct(CSPBuilder|array $csp, array $config = [])
    {
        if (!class_exists(CSPBuilder::class)) {
            throw new CakeException('You must install paragonie/csp-builder to use CspMiddleware');
        }
        $this->setConfig($config);

        if (!$csp instanceof CSPBuilder) {
            $csp = new CSPBuilder($csp);
        }

        $this->csp = $csp;
    }

    /**
     * Add nonces (if enabled) to the request and apply the CSP header to the response.
     *
     * @param \Psr\Http\Message\ServerRequestInterface $request The request.
     * @param \Psr\Http\Server\RequestHandlerInterface $handler The request handler.
     * @return \Psr\Http\Message\ResponseInterface A response.
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface

View on GitHub (pinned to 1128eba9b0)