{"record":{"id":"72cc3e203948606c","repo":"ramsey/uuid","slug":"invalid-number-of-bytes","errorCode":null,"errorMessage":"Invalid number of bytes","messagePattern":"Invalid number of bytes","errorType":"exception","errorClass":"InvalidBytesException","httpStatus":null,"severity":"error","filePath":"src/Rfc4122/VariantTrait.php","lineNumber":58,"sourceCode":"\n    /**\n     * Returns the variant\n     *\n     * The variant number describes the layout of the UUID. The variant number has the following meaning:\n     *\n     * - 0 - Reserved for NCS backward compatibility\n     * - 2 - The RFC 9562 (formerly RFC 4122) variant\n     * - 6 - Reserved, Microsoft Corporation backward compatibility\n     * - 7 - Reserved for future definition\n     *\n     * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`.\n     *\n     * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field\n     */\n    public function getVariant(): int\n    {\n        if (strlen($this->getBytes()) !== 16) {\n            throw new InvalidBytesException('Invalid number of bytes');\n        }\n\n        // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and\n        // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 5.10}, the Max UUID falls within the range\n        // of the future variant.\n        if ($this->isMax()) {\n            return Uuid::RESERVED_FUTURE;\n        }\n\n        // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and\n        // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 5.9}, the Nil UUID falls within the range\n        // of the Apollo NCS variant.\n        if ($this->isNil()) {\n            return Uuid::RESERVED_NCS;\n        }\n\n        /** @var int[] $parts */\n        $parts = unpack('n*', $this->getBytes());","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/ramsey/uuid/blob/da5b521600a707d2dd097598464bd3090de850f5/src/Rfc4122/VariantTrait.php#L40-L76","documentation":"VariantTrait::getVariant() reads the variant bits from the UUID's internal 16-byte string and first asserts strlen($this->getBytes()) === 16, throwing Ramsey\\Uuid\\Exception\\InvalidBytesException ('Invalid number of bytes') when the length differs. The trait is shared by Ramsey\\Uuid\\Rfc4122\\Fields, Guid\\Fields and Nonstandard\\Fields, whose constructors validate length eagerly — so reaching this throw usually means a custom Fields implementation using VariantTrait, or a byte string that was truncated/corrupted. Any byte count other than exactly 16 (15, 17, 32...) triggers it.","triggerScenarios":"Calling getVariant() on fields built from a byte string that is not exactly 16 bytes — e.g. hex2bin() of a 30-character hex string (15 bytes), substr($bytes, 0, 15) truncation in a custom codec, or a custom Fields class using VariantTrait without validating its input length.","commonSituations":"Binary UUID columns truncated by a database (CHAR(15) instead of BINARY(16)); custom builders on GUID systems reordering 16 bytes with substr offsets; hand-built hex pads shorter than 32 characters; bitwise copy/paste errors in byte manipulation code.","solutions":["Ensure the byte string is exactly 16 bytes before constructing fields: pad hex to 32 characters with str_pad($hex, 32, '0', STR_PAD_LEFT) before hex2bin()","Prefer Uuid::fromBytes($bytes) or Uuid::fromString($string) — their validators reject wrong lengths with a clearer error up front","In a custom Fields implementation, validate strlen($bytes) === 16 in the constructor so the error surfaces at creation time","Check the storage schema (BINARY(16)) and any transport encoding that might truncate the value"],"exampleFix":"// before: hex string is 30 chars -> 15 bytes\n$bytes = hex2bin('e4b8adce621111e3b9a19b01aaa2');\n$fields = new CustomFields($bytes);\n$variant = $fields->getVariant(); // InvalidBytesException: Invalid number of bytes\n\n// after: pad to 32 hex chars so the byte string is exactly 16 bytes\n$bytes = hex2bin(str_pad('e4b8adce621111e3b9a19b01aaa2', 32, '0', STR_PAD_LEFT));\n$fields = new CustomFields($bytes);\n$variant = $fields->getVariant(); // 2 (RFC 9562 variant)","handlingStrategy":"validation","validationCode":"// Run before building fields from raw bytes\nif (strlen($bytes) !== 16) {\n    throw new \\InvalidArgumentException(\n        sprintf('UUID bytes must be exactly 16 bytes, got %d', strlen($bytes))\n    );\n}\n\n// Or when starting from hex, pad/validate first\n$hex = str_pad($hex, 32, '0', STR_PAD_LEFT);\nif (strlen($hex) !== 32 || !ctype_xdigit($hex)) {\n    throw new \\InvalidArgumentException('Expected a 32-character hex string');\n}\n$bytes = hex2bin($hex);","typeGuard":"function isUuidByteString(string $bytes): bool\n{\n    return strlen($bytes) === 16;\n}","tryCatchPattern":"use Ramsey\\Uuid\\Exception\\InvalidBytesException;\n\ntry {\n    $variant = $fields->getVariant();\n} catch (InvalidBytesException $e) {\n    // reject/re-request the input; do not guess a variant\n}","preventionTips":["Always feed exactly 16 bytes (32 hex characters) into field construction","Prefer Uuid::fromBytes()/fromString() — their validators reject wrong lengths early with clearer errors","In custom Fields classes, validate length in the constructor","Use BINARY(16) columns and length-checked transports for UUID storage"],"tags":["php","ramsey-uuid","uuid","bytes","length-validation","variant"],"backgroundTag":"invalid-byte-length","analyzedSha":"da5b521600a707d2dd097598464bd3090de850f5","analyzedAt":"2026-08-21T01:35:29.252Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}