{"record":{"id":"a5674de7595e691c","repo":"lcobucci/jwt","slug":"error-while-encoding-to-json","errorCode":null,"errorMessage":"Error while encoding to JSON","messagePattern":"Error while encoding to JSON","errorType":"exception","errorClass":"Lcobucci\\JWT\\Encoding\\CannotEncodeContent","httpStatus":null,"severity":"error","filePath":"src/Encoding/JoseEncoder.php","lineNumber":28,"sourceCode":"\nuse function json_decode;\nuse function json_encode;\n\nuse const JSON_THROW_ON_ERROR;\nuse const JSON_UNESCAPED_SLASHES;\nuse const JSON_UNESCAPED_UNICODE;\n\n/**\n * A utilitarian class that encodes and decodes data according to JOSE specifications\n */\nfinal readonly class JoseEncoder implements Encoder, Decoder\n{\n    public function jsonEncode(mixed $data): string\n    {\n        try {\n            return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);\n        } catch (JsonException $exception) {\n            throw CannotEncodeContent::jsonIssues($exception);\n        }\n    }\n\n    public function jsonDecode(string $json): mixed\n    {\n        try {\n            return json_decode(json: $json, associative: true, flags: JSON_THROW_ON_ERROR);\n        } catch (JsonException $exception) {\n            throw CannotDecodeContent::jsonIssues($exception);\n        }\n    }\n\n    public function base64UrlEncode(string $data): string\n    {\n        return SodiumBase64Polyfill::bin2base64(\n            $data,\n            SodiumBase64Polyfill::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING,\n        );","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Encoding/JoseEncoder.php#L10-L46","documentation":"JoseEncoder::jsonEncode() calls json_encode with JSON_THROW_ON_ERROR (plus JSON_UNESCAPED_SLASHES and JSON_UNESCAPED_UNICODE). If encoding fails, JsonException is caught and rethrown as CannotEncodeContent::jsonIssues($exception) with the message 'Error while encoding to JSON'. Common causes are malformed UTF-8, resources/closures/inf/nan values, or exceeding recursion/depth limits.","triggerScenarios":"Passing data to jsonEncode() that json_encode cannot serialize: strings with invalid UTF-8, INF/NAN floats, resources or closures, or structures deeper than 512 levels (depth limit).","commonSituations":"Injecting claims built from raw binary or invalid-encoding database content into a JWT; accidentally putting a resource (e.g. from fopen) in a claim; deeply nested arrays from decoded payloads; locale/encoding mismatches producing non-UTF-8 strings.","solutions":["Inspect the chained JsonException via $e->getPrevious() (it carries the precise json_encode error code, e.g. JSON_ERROR_UTF8) to identify the offending value.","Sanitize input to valid UTF-8 (e.g. mb_convert_encoding($value, 'UTF-8', 'UTF-8') or remove invalid sequences) before encoding.","Remove non-scalar claim values (resources, closures) and replace INF/NAN with finite values.","Reduce nesting depth below json_encode's 512-level limit for deeply nested payloads."],"exampleFix":"// before\n$token = $builder->withClaim('data', $rawFromDb)->getToken(...); // CannotEncodeContent\n// after\n$data = mb_convert_encoding($rawFromDb, 'UTF-8', 'UTF-8');\n$token = $builder->withClaim('data', $data)->getToken(...);","handlingStrategy":"try-catch","validationCode":"// Cheap pre-checks for the common failure modes\nfunction isJsonEncodableSafe(mixed $value): bool\n{\n    if (is_string($value) && !preg_match('//u', $value)) {\n        return false; // invalid UTF-8\n    }\n    if (is_float($value) && (is_infinite($value) || is_nan($value))) {\n        return false;\n    }\n    return is_scalar($value) || $value === null || is_array($value);\n}","typeGuard":null,"tryCatchPattern":"use Lcobucci\\JWT\\Encoding\\CannotEncodeContent;\n\ntry {\n    $json = $encoder->jsonEncode($data);\n} catch (CannotEncodeContent $e) {\n    $jsonError = $e->getPrevious(); // JsonException with the precise json_encode error\n    // sanitize/reject $data based on $jsonError->getCode()\n}","preventionTips":["Force UTF-8 on all strings (especially from databases or external APIs) before using them as JWT claims.","Never place resources, closures, INF/NAN floats, or deeply nested (>512 levels) structures in claims.","Run json_encode with JSON_THROW_ON_ERROR on the same data first in development to catch issues early.","Keep the previous JsonException (getPrevious()) in logs — its code pinpoints the exact encoding problem."],"tags":["json","encoding","jwt"],"backgroundTag":"json-marshal-failed","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}