ramsey/uuid · error · UnsupportedOperationException

Attempted to unserialize an invalid value

Error message

Attempted to unserialize an invalid value

What it means

Ramsey\Uuid\Type\Time is the value object for timestamp parts (seconds plus microseconds). Its legacy unserialize(string $data) entry point json_decode()s the stored string and requires both 'seconds' and 'microseconds' keys; if either is missing it throws Ramsey\Uuid\Exception\UnsupportedOperationException. This fires when the serialized representation being restored is not the JSON pair this class writes — corrupted, foreign, or hand-built payloads.

Source

Thrown at src/Type/Time.php:110

    {
        return [
            'seconds' => $this->getSeconds()->toString(),
            'microseconds' => $this->getMicroseconds()->toString(),
        ];
    }

    /**
     * Constructs the object from a serialized string representation
     *
     * @param string $data The serialized string representation of the object
     */
    public function unserialize(string $data): void
    {
        /** @var array{seconds?: float | int | string, microseconds?: float | int | string} $time */
        $time = json_decode($data, true);

        if (!isset($time['seconds']) || !isset($time['microseconds'])) {
            throw new UnsupportedOperationException('Attempted to unserialize an invalid value');
        }

        $this->__construct($time['seconds'], $time['microseconds']);
    }

    /**
     * @param array{seconds?: string, microseconds?: string} $data
     */
    public function __unserialize(array $data): void
    {
        // @codeCoverageIgnoreStart
        if (!isset($data['seconds']) || !isset($data['microseconds'])) {
            throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__));
        }
        // @codeCoverageIgnoreEnd

        $this->__construct($data['seconds'], $data['microseconds']);
    }

View on GitHub (pinned to da5b521600)

Solutions

  1. Construct the value directly instead of restoring it: new Time($seconds, $microseconds)
  2. Store the components (or a single integer timestamp) and rebuild Time on read
  3. Catch UnsupportedOperationException at the cache layer and treat the entry as a miss
  4. Regenerate/flush stale serialized entries after any serialization format change

Example fix

// before
$time = unserialize($cachedPayload);
// UnsupportedOperationException: Attempted to unserialize an invalid value

// after: store components and rebuild
$time = new Time($cachedSeconds, $cachedMicroseconds);
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the JSON shape before calling unserialize() manually
$decoded = json_decode($data, true);
if (!is_array($decoded) || !isset($decoded['seconds'], $decoded['microseconds'])) {
    throw new \InvalidArgumentException('Time payload must contain seconds and microseconds');
}
$time->unserialize($data);

Try / catch

use Ramsey\Uuid\Exception\UnsupportedOperationException;

try {
    $time = unserialize($cachedPayload);
} catch (UnsupportedOperationException $e) {
    // malformed stored Time: rebuild from source timestamps
    $time = new Ramsey\Uuid\Type\Time($seconds, $microseconds);
}

Prevention

When it happens

Trigger: Calling unserialize() on a serialized Time object whose stored body is not JSON containing both keys — e.g. a cache entry from an incompatible format, a truncated payload, or calling $time->unserialize('garbage') directly in legacy Serializable-style code.

Common situations: Caches or queues carrying serialized Time objects written by older/other code; storage truncation of serialized blobs; partial payloads after failed writes; migrations between serialization libraries.

Related errors


AI-assisted analysis of ramsey/uuid@da5b521600 (2026-08-21). Data as JSON: /api/errors/0432a8b4d8334222. Report an issue: GitHub.