ramsey/uuid · error · InvalidArgumentException
$bytes string should contain 16 characters.
Error message
$bytes string should contain 16 characters.
What it means
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.
Source
Thrown at src/Codec/OrderedTimeCodec.php:80
/** @phpstan-ignore possiblyImpure.methodCall */
$bytes = $uuid->getFields()->getBytes();
return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5]
. $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]
. substr($bytes, 8);
}
/**
* Returns a UuidInterface derived from an ordered-time binary string representation
*
* @throws InvalidArgumentException if $bytes is an invalid length
*
* @inheritDoc
*/
public function decodeBytes(string $bytes): UuidInterface
{
if (strlen($bytes) !== 16) {
throw new InvalidArgumentException('$bytes string should contain 16 characters.');
}
// Rearrange the bytes to their original order.
$rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7]
. $bytes[2] . $bytes[3] . $bytes[0] . $bytes[1]
. substr($bytes, 8);
$uuid = parent::decodeBytes($rearrangedBytes);
/** @phpstan-ignore possiblyImpure.methodCall */
$fields = $uuid->getFields();
if (!$fields instanceof Rfc4122FieldsInterface || $fields->getVersion() !== Uuid::UUID_TYPE_TIME) {
throw new UnsupportedOperationException(
'Attempting to decode a non-time-based UUID using OrderedTimeCodec',
);
}
View on GitHub (pinned to da5b521600)
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.
Example fix
// before
$uuid = $orderedCodec->decodeBytes($row['id']); // hex string, 32 chars
// after
$bytes = (string) hex2bin($row['id']);
if (strlen($bytes) !== 16) {
throw new RuntimeException('expected 16 bytes');
}
$uuid = $orderedCodec->decodeBytes($bytes); Defensive patterns
Strategy: validation
Validate before calling
function assertOrderedTimeBytes(string $bytes): void
{
if (strlen($bytes) === 32 && ctype_xdigit($bytes)) {
throw new InvalidArgumentException('value looks like hex; run hex2bin() first');
}
if (strlen($bytes) !== 16) {
throw new InvalidArgumentException(sprintf('expected 16 bytes, got %d', strlen($bytes)));
}
}
assertOrderedTimeBytes($bytes);
$uuid = $orderedCodec->decodeBytes($bytes); Type guard
function isUuidByteString(string $value): bool
{
return strlen($value) === 16;
} Try / catch
try {
$uuid = $orderedCodec->decodeBytes($bytes);
} catch (\Ramsey\Uuid\Exception\InvalidArgumentException $e) {
// length guard fired: reject or repair the stored value
throw new StoredIdentifierCorruptException($row['id'], $e);
} Prevention
- 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.
When it happens
Trigger: $codec->decodeBytes($hexString) with 32 hex characters; passing the canonical 'xxxxxxxx-xxxx-...' string; decoding a value truncated by transport, column width, or string concatenation.
Common situations: 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.
Related errors
- Attempting to decode a non-time-based UUID using OrderedTime
- $bytes string should contain 16 characters.
- Could not find a suitable builder for the provided codec and
- Expected version 1 (time-based) UUID
- Invalid UUID string: {encodedUuid}
AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21).
Data as JSON: /api/errors/5246f8f2d31a7488.
Report an issue: GitHub.