ramsey/uuid · error · ValueError
%s(): Argument #1 ($data) is invalid
Error message
%s(): Argument #1 ($data) is invalid
What it means
When PHP unserializes a Ramsey\Uuid\Uuid object, __unserialize(array $data) requires the array key 'bytes' (the 16-byte string emitted by __serialize()/serialize()). A payload missing that key throws a native ValueError with a message styled like PHP's internal argument errors. Serialized UUID objects in caches, sessions or queues become malformed when truncated, written by other code, or hand-built.
Source
Thrown at src/Uuid.php:349
/** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */
$this->numberConverter = $uuid->numberConverter;
/** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */
$this->fields = $uuid->fields;
/** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */
$this->timeConverter = $uuid->timeConverter;
}
/**
* @param array{bytes?: string} $data
*/
public function __unserialize(array $data): void
{
// @codeCoverageIgnoreStart
if (!isset($data['bytes'])) {
throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));
}
// @codeCoverageIgnoreEnd
$this->unserialize($data['bytes']);
}
public function compareTo(UuidInterface $other): int
{
$compare = strcmp($this->toString(), $other->toString());
if ($compare < 0) {
return -1;
}
if ($compare > 0) {
return 1;
}
View on GitHub (pinned to da5b521600)
Solutions
- Store the canonical UUID string instead and rebuild with Uuid::fromString($string) on read
- Treat the malformed entry as a cache miss and regenerate the value
- Flush/expire stale serialized entries after deploying serialization changes
- Align library versions between the writer and reader of the shared store
Example fix
// before $uuid = unserialize($cachedUuid); // ValueError: Ramsey\Uuid\Uuid::__unserialize(): Argument #1 ($data) is invalid // after: cache the canonical string and rebuild $uuid = Uuid::fromString($cachedUuidString); // e.g. 'a3f3df0e-6f8b-4c1a-9d2e-4b0c8f7a1d23'
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate shape before trusting a stored payload
$decoded = unserialize($cached, ['allowed_classes' => false]);
if (!(is_array($decoded) && isset($decoded['bytes']))) {
// treat as cache miss; rebuild from the canonical string
$uuid = Ramsey\Uuid\Uuid::fromString($uuidString);
} Try / catch
use Ramsey\Uuid\Uuid;
try {
$restored = unserialize($cached);
} catch (\ValueError $e) {
$restored = Uuid::fromString($canonicalString); // rebuild from the stored text form
} Prevention
- Persist UUIDs as their canonical 36-character string (or 32 hex) and rebuild via Uuid::fromString()
- Avoid caching serialized Uuid objects across deploys
- Catch ValueError when unserializing anything from storage and fall back to reconstruction
- Version cache keys to force invalidation after serialization changes
When it happens
Trigger: unserialize() of a stored Uuid payload whose array body lacks 'bytes' — e.g. cache entries from a different producer, truncated serialized blobs, or serialized data passed through unserialize() with allowed_classes reshaping.
Common situations: UUIDs cached as serialized objects in Redis/sessions; queue messages carrying serialized UUIDs across service versions; corrupted storage after crashes; test fixtures with literal serialized strings.
Related errors
- %s(): Argument #1 ($data) is invalid
- %s(): Argument #1 ($data) is invalid
- %s(): Argument #1 ($data) is invalid
- %s(): Argument #1 ($data) is invalid
- %s(): Argument #1 ($data) is invalid
AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21).
Data as JSON: /api/errors/0ce670bfd7b24753.
Report an issue: GitHub.