{"record":{"id":"5ff9d4cdddb7feed","repo":"symfony/var-dumper","slug":"the-nonce-closure-passed-to-s-setnonce-must-return-a-string","errorCode":null,"errorMessage":"The nonce closure passed to \"%s::setNonce()\" must return a string or null, \"%s\" returned.","messagePattern":"The nonce closure passed to \"(.+?)::setNonce\\(\\)\" must return a string or null, \"(.+?)\" returned\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"Dumper/HtmlDumper.php","lineNumber":178,"sourceCode":"        if (null !== $styleNonce) {\n            $replacements['<style>'] = '<style nonce=\"'.esc($styleNonce).'\">';\n        }\n\n        if (!$replacements) {\n            return $html;\n        }\n\n        return str_replace(array_keys($replacements), array_values($replacements), $html);\n    }\n\n    private function resolveNonce(string|\\Closure|null $nonce): ?string\n    {\n        if (!$nonce instanceof \\Closure) {\n            return $nonce;\n        }\n\n        if (!\\is_string(($value = $nonce()) ?? '')) {\n            throw new \\LogicException(\\sprintf('The nonce closure passed to \"%s::setNonce()\" must return a string or null, \"%s\" returned.', self::class, get_debug_type($value)));\n        }\n\n        return $value;\n    }\n\n    public function dump(Data $data, $output = null, array $extraDisplayOptions = []): ?string\n    {\n        $this->extraDisplayOptions = $extraDisplayOptions;\n        $result = parent::dump($data, $output);\n        $this->dumpId = 'sf-dump-'.mt_rand();\n\n        return $result;\n    }\n\n    /**\n     * Dumps the HTML header.\n     */\n    protected function getDumpHeader(): string","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/symfony/var-dumper/blob/e9d9cf5dcdd4b1b13b4504aaffd66ce4ddb5684e/Dumper/HtmlDumper.php#L160-L196","documentation":"HtmlDumper::setNonce() accepts a string, null, or a Closure returning string|null. resolveNonce() invokes the closure and validates the return; if it returns a non-string non-null value (int, bool, object, etc.), a LogicException is thrown naming the expected types.","triggerScenarios":"`$dumper->setNonce(fn () => 12345)` or a closure returning an int, bool, Stringable object, or array instead of string or null.","commonSituations":"CSP nonce helpers that return integer IDs or objects; closures reading config values that are not cast to string; returning false as a 'missing' sentinel instead of null.","solutions":["Ensure the closure returns a string or null; cast with (string) or return null when no nonce","If using a bool/false sentinel, change it to return null","Fix the nonce provider (e.g. cast $request->attributes->get('_csp_nonce') to string) feeding the closure"],"exampleFix":"// before\n$dumper->setNonce(fn () => $nonceId);\n// after\n$dumper->setNonce(fn () => $nonceId !== null ? (string) $nonceId : null);","handlingStrategy":"type-guard","validationCode":"$resolved = $nonce instanceof \\Closure ? $nonce() : $nonce;\nif ($resolved !== null && !is_string($resolved)) {\n    throw new \\TypeError('Nonce must resolve to string or null, got '.get_debug_type($resolved));\n}","typeGuard":"function isValidNonce(mixed $resolved): bool {\n    return $resolved === null || is_string($resolved);\n}","tryCatchPattern":"try {\n    $dumper->setNonce($nonceProvider);\n} catch (\\LogicException $e) {\n    if (str_contains($e->getMessage(), 'setNonce()')) {\n        $dumper->setNonce(null); // fall back to no CSP nonce\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Typehint the nonce closure return as ?string: `fn (): ?string => ...`","Cast nonce IDs to string and use null (not false/0) as the missing sentinel","Unit-test any CSP nonce provider closure for its return type"],"tags":["csp","nonce","type-error"],"backgroundTag":"type-mismatch","analyzedSha":"e9d9cf5dcdd4b1b13b4504aaffd66ce4ddb5684e","analyzedAt":"2026-09-14T11:19:53.665Z","contentChangedAt":"2026-09-14T11:19:53.665Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}