ramsey/uuid · error · ValueError

%s(): Argument #1 ($data) is invalid

Error message

%s(): Argument #1 ($data) is invalid

What it means

LazyUuidFromString is the lazy wrapper Uuid::fromString() returns; PHP calls __unserialize(array $data) when restoring it via unserialize(). The serialized payload must be an array containing a 'string' key (produced by the matching __serialize). If the array lacks that key, sprintf() builds a ValueError naming the method — mirroring PHP's own internal-argument error style.

Source

Thrown at src/Lazy/LazyUuidFromString.php:111

    /**
     * {@inheritDoc}
     *
     * @param non-empty-string $data
     */
    public function unserialize(string $data): void
    {
        $this->uuid = $data;
    }

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

        $this->unserialize($data['string']);
    }

    public function getNumberConverter(): NumberConverterInterface
    {
        return ($this->unwrapped ?? $this->unwrap())->getNumberConverter();
    }

    /**
     * @inheritDoc
     */
    public function getFieldsHex(): array
    {
        return ($this->unwrapped ?? $this->unwrap())->getFieldsHex();
    }

View on GitHub (pinned to da5b521600)

Solutions

  1. Do not build serialization payloads by hand — only unserialize() strings created by serialize() of the same class
  2. Re-generate cached serialized UUIDs after upgrading ramsey/uuid (store the canonical string form instead)
  3. Store Uuid objects as their 36-char string and call Uuid::fromString() on read, avoiding object serialization entirely

Example fix

// before
$payload = ['uuid' => ['str' => '...']]; // hand-made, wrong key
$obj = unserialize(serialize($payload['uuid']));

// after
$payload = ['uuid' => 'a3f0f0c8-0f4b-11ef-9f3f-0242ac110002'];
$uuid = \Ramsey\Uuid\Uuid::fromString($payload['uuid']);
Defensive patterns

Strategy: try-catch

Validate before calling

$data = unserialize($serialized);
if (!is_array($data) || !isset($data['string'])) {
    throw new RuntimeException('Corrupt LazyUuidFromString payload: missing string key');
}

Try / catch

try {
    $obj = unserialize($blob);
} catch (\ValueError $e) {
    // payload not produced by __serialize of this class; rebuild from string form
    $obj = \Ramsey\Uuid\Uuid::fromString($knownString);
}

Prevention

When it happens

Trigger: Manually crafting an unserialize payload (e.g. unserialize('O:44:"Ramsey\\Uuid\\Lazy\\LazyUuidFromString":1:{a:0:{}}') style structures), double-serializing/wrapping the object, or feeding unserialize() a string produced by a different ramsey/uuid version or a different class that maps into this one.

Common situations: Cached serialized UUID objects across library upgrades; queue/session payloads hand-assembled or truncated; using var_export()/eval tricks instead of serialize(); data corrupted in storage.

Related errors


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