{"record":{"id":"5246f8f2d31a7488","repo":"ramsey/uuid","slug":"bytes-string-should-contain-16-characters","errorCode":null,"errorMessage":"$bytes string should contain 16 characters.","messagePattern":"\\$bytes string should contain 16 characters\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Codec/OrderedTimeCodec.php","lineNumber":80,"sourceCode":"        /** @phpstan-ignore possiblyImpure.methodCall */\n        $bytes = $uuid->getFields()->getBytes();\n\n        return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5]\n            . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]\n            . substr($bytes, 8);\n    }\n\n    /**\n     * Returns a UuidInterface derived from an ordered-time binary string representation\n     *\n     * @throws InvalidArgumentException if $bytes is an invalid length\n     *\n     * @inheritDoc\n     */\n    public function decodeBytes(string $bytes): UuidInterface\n    {\n        if (strlen($bytes) !== 16) {\n            throw new InvalidArgumentException('$bytes string should contain 16 characters.');\n        }\n\n        // Rearrange the bytes to their original order.\n        $rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7]\n            . $bytes[2] . $bytes[3] . $bytes[0] . $bytes[1]\n            . substr($bytes, 8);\n\n        $uuid = parent::decodeBytes($rearrangedBytes);\n\n        /** @phpstan-ignore possiblyImpure.methodCall */\n        $fields = $uuid->getFields();\n\n        if (!$fields instanceof Rfc4122FieldsInterface || $fields->getVersion() !== Uuid::UUID_TYPE_TIME) {\n            throw new UnsupportedOperationException(\n                'Attempting to decode a non-time-based UUID using OrderedTimeCodec',\n            );\n        }\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/ramsey/uuid/blob/da5b521600a707d2dd097598464bd3090de850f5/src/Codec/OrderedTimeCodec.php#L62-L98","documentation":"OrderedTimeCodec::decodeBytes() expects the 16-byte rearranged binary form that OrderedTimeCodec::encodeBinary() produces. It throws InvalidArgumentException the moment strlen($bytes) !== 16, before any byte rearranging happens. Anything that is not raw 16-byte ordered-time data - hex text, hyphenated strings, base64, truncated values - fails here.","triggerScenarios":"$codec->decodeBytes($hexString) with 32 hex characters; passing the canonical 'xxxxxxxx-xxxx-...' string; decoding a value truncated by transport, column width, or string concatenation.","commonSituations":"UUID column stored as CHAR(36) or hex text instead of BINARY(16); values hex-encoded for JSON transport and not converted back; reading via an ORM getter that formats bytes as hex.","solutions":["Convert back to raw bytes: (string) hex2bin($hex) or base64_decode($b64) before decoding.","Validate strlen($bytes) === 16 before calling decodeBytes().","Store ordered-time UUIDs in a BINARY(16) column so length cannot drift."],"exampleFix":"// before\n$uuid = $orderedCodec->decodeBytes($row['id']); // hex string, 32 chars\n\n// after\n$bytes = (string) hex2bin($row['id']);\nif (strlen($bytes) !== 16) {\n    throw new RuntimeException('expected 16 bytes');\n}\n$uuid = $orderedCodec->decodeBytes($bytes);","handlingStrategy":"validation","validationCode":"function assertOrderedTimeBytes(string $bytes): void\n{\n    if (strlen($bytes) === 32 && ctype_xdigit($bytes)) {\n        throw new InvalidArgumentException('value looks like hex; run hex2bin() first');\n    }\n    if (strlen($bytes) !== 16) {\n        throw new InvalidArgumentException(sprintf('expected 16 bytes, got %d', strlen($bytes)));\n    }\n}\n\nassertOrderedTimeBytes($bytes);\n$uuid = $orderedCodec->decodeBytes($bytes);","typeGuard":"function isUuidByteString(string $value): bool\n{\n    return strlen($value) === 16;\n}","tryCatchPattern":"try {\n    $uuid = $orderedCodec->decodeBytes($bytes);\n} catch (\\Ramsey\\Uuid\\Exception\\InvalidArgumentException $e) {\n    // length guard fired: reject or repair the stored value\n    throw new StoredIdentifierCorruptException($row['id'], $e);\n}","preventionTips":["Normalize once at the storage boundary (hex2bin/base64_decode + length assert) and pass bytes onward.","Use BINARY(16) columns for ordered-time UUIDs.","Never feed formatted UUID strings (hyphens, URN, braces) to decodeBytes().","Centralize decode calls in a repository instead of scattering them where inputs vary."],"tags":["php","ramsey-uuid","ordered-time-codec","decode-bytes","length-check"],"backgroundTag":"uuid-bytes-length-invalid","analyzedSha":"da5b521600a707d2dd097598464bd3090de850f5","analyzedAt":"2026-08-21T01:35:29.252Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}