{"record":{"id":"d043ef6d40ab4fe8","repo":"twigphp/Twig","slug":"the-s-attribute-value-cannot-be-json-encoded","errorCode":null,"errorMessage":"The \"%s\" attribute value cannot be JSON encoded.","messagePattern":"The \"(.+?)\" attribute value cannot be JSON encoded\\.","errorType":"exception","errorClass":"Twig\\Error\\RuntimeError","httpStatus":null,"severity":"error","filePath":"extra/html-extra/HtmlExtension.php","lineNumber":247,"sourceCode":"        }\n\n        if (str_starts_with($name, 'aria-')) {\n            // For aria-*, convert booleans to \"true\" and \"false\" strings\n            if (true === $value) {\n                $value = 'true';\n            } elseif (false === $value) {\n                $value = 'false';\n            }\n        }\n\n        if (str_starts_with($name, 'data-')) {\n            if (!$value instanceof AttributeValueInterface && !$value instanceof \\Stringable && null !== $value && !\\is_scalar($value)) {\n                // ... encode non-null non-scalars as JSON, but leave the string representation\n                // of a Stringable alone, as it is already the value the object asks to render as\n                try {\n                    $value = json_encode($value, \\JSON_THROW_ON_ERROR);\n                } catch (\\JsonException $e) {\n                    throw new RuntimeError(\\sprintf('The \"%s\" attribute value cannot be JSON encoded.', $name), previous: $e);\n                }\n            } elseif (true === $value) {\n                // ... and convert boolean true to a 'true'  string.\n                $value = 'true';\n            }\n        }\n\n        // Convert iterable values to token lists\n        if (!$value instanceof AttributeValueInterface && is_iterable($value)) {\n            if ('style' === $name) {\n                $value = new InlineStyle($value);\n            } else {\n                $value = new SeparatedTokenList($value);\n            }\n        }\n\n        if ($value instanceof AttributeValueInterface) {\n            $value = $value->getValue();","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/extra/html-extra/HtmlExtension.php#L229-L265","documentation":"html_attr_value() JSON-encodes non-scalar, non-Stringable, non-null attribute values so they can be rendered. If json_encode() with JSON_THROW_ON_ERROR fails (e.g. malformed UTF-8, recursion, unsupported resources), the JsonException is wrapped in this RuntimeError with the attribute name for context.","triggerScenarios":"Passing an array/object containing resources, circular references or invalid UTF-8 strings as an attribute value in html_attr().","commonSituations":"Binary data or malformed UTF-8 from legacy databases placed into attributes; recursively-referencing objects; DOMDocument or PDO objects accidentally passed as values.","solutions":["Fix the underlying data: sanitize invalid UTF-8 (e.g. mb_convert_encoding($s, 'UTF-8', 'UTF-8')).","Implement Stringable on the value object so it is used verbatim instead of JSON-encoded.","Convert the value to a scalar/array of scalars before passing.","Inspect $e->getPrevious() (the JsonException) to see the exact encoding failure."],"exampleFix":"// before\nhtml_attr(['data-payload' => $rawBinary])\n// after\nhtml_attr(['data-payload' => base64_encode($rawBinary)])","handlingStrategy":"try-catch","validationCode":"foreach ($values as $v) { if (!is_scalar($v) && !$v instanceof \\Stringable && null !== $v) json_encode($v, JSON_THROW_ON_ERROR); }","typeGuard":"function isJsonEncodableAttr(mixed $v): bool { try { if (is_scalar($v) || $v instanceof \\Stringable || null === $v) return true; json_encode($v, JSON_THROW_ON_ERROR); return true; } catch (\\JsonException) { return false; } }","tryCatchPattern":"try { $html = html_attr($attrs); } catch (Twig\\Error\\RuntimeError $e) { if ($e->getPrevious() instanceof \\JsonException) { /* sanitize and retry */ } throw $e; }","preventionTips":["Sanitize strings to valid UTF-8 before using as attributes","Prefer scalars or Stringable objects for attribute values","Base64-encode binary payloads"],"tags":["twig","json","html-attr"],"backgroundTag":"json-marshal-failed","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}