{"record":{"id":"52c12e25070a57e2","repo":"cakephp/cakephp","slug":"you-must-install-paragonie-csp-builder-to-use-cspmiddleware","errorCode":null,"errorMessage":"You must install paragonie/csp-builder to use CspMiddleware","messagePattern":"You must install paragonie/csp-builder to use CspMiddleware","errorType":"exception","errorClass":"Cake\\Core\\Exception\\CakeException","httpStatus":null,"severity":"error","filePath":"src/Http/Middleware/CspMiddleware.php","lineNumber":66,"sourceCode":"     * Configuration options.\n     *\n     * @var array<string, mixed>\n     */\n    protected array $_defaultConfig = [\n        'scriptNonce' => false,\n        'styleNonce' => false,\n    ];\n\n    /**\n     * Constructor\n     *\n     * @param \\ParagonIE\\CSPBuilder\\CSPBuilder|array $csp CSP object or config array\n     * @param array<string, mixed> $config Configuration options.\n     */\n    public function __construct(CSPBuilder|array $csp, array $config = [])\n    {\n        if (!class_exists(CSPBuilder::class)) {\n            throw new CakeException('You must install paragonie/csp-builder to use CspMiddleware');\n        }\n        $this->setConfig($config);\n\n        if (!$csp instanceof CSPBuilder) {\n            $csp = new CSPBuilder($csp);\n        }\n\n        $this->csp = $csp;\n    }\n\n    /**\n     * Add nonces (if enabled) to the request and apply the CSP header to the response.\n     *\n     * @param \\Psr\\Http\\Message\\ServerRequestInterface $request The request.\n     * @param \\Psr\\Http\\Server\\RequestHandlerInterface $handler The request handler.\n     * @return \\Psr\\Http\\Message\\ResponseInterface A response.\n     */\n    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/Http/Middleware/CspMiddleware.php#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `composer require paragonie/csp-builder`","Verify vendor/paragonie/csp-builder exists on the deployed host and the autoloader was regenerated (composer dump-autoload)","If you only need static CSP headers, set them manually via SecurityHeadersMiddleware instead of CspMiddleware"],"exampleFix":"// before\n$middleware->add(new CspMiddleware(['default-src' => ['self']]));\n// after (first run)\n// composer require paragonie/csp-builder\n$middleware->add(new CspMiddleware(['default-src' => ['self']]));","handlingStrategy":"fallback","validationCode":"if (!class_exists(\\ParagonIE\\CSPBuilder\\CSPBuilder::class)) {\n    // skip or install\n}","typeGuard":"function isCspBuilderInstalled(): bool { return class_exists(\\ParagonIE\\CSPBuilder\\CSPBuilder::class); }","tryCatchPattern":"try {\n    $middleware->add(new CspMiddleware($config));\n} catch (\\Cake\\Core\\Exception\\CakeException $e) {\n    // fall back to manual header middleware or surface install instructions\n}","preventionTips":["composer require paragonie/csp-builder before using CspMiddleware","Keep the package in require (not require-dev) since middleware runs in production","Check deployed vendor tree includes the package"],"tags":["dependency","composer","middleware","csp"],"backgroundTag":"missing-optional-dependency","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}