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\Type\Decimal object, __unserialize(array $data) runs and requires the array key 'string' (the shape produced by __serialize()). If the payload lacks that key, a native ValueError is thrown with a message mimicking PHP's internal argument errors. This indicates the serialized payload does not match the class's expected serialization shape — corrupted data, hand-crafted payloads, or a different format written by other code.

Source

Thrown at src/Type/Decimal.php:119

    /**
     * Constructs the object from a serialized string representation
     *
     * @param string $data The serialized string representation of the object
     */
    public function unserialize(string $data): void
    {
        $this->__construct($data);
    }

    /**
     * @param array{string?: 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']);
    }
}

View on GitHub (pinned to da5b521600)

Solutions

  1. Stop unserializing the stale payload and rebuild the object: $decimal = new Decimal($rawString)
  2. Invalidate/flush the cache or session entries holding the malformed payloads
  3. Ensure every environment that reads the cache runs a compatible version of the code that wrote it
  4. Prefer storing scalar values (the decimal string) and constructing Decimal on read instead of serializing objects

Example fix

// before
$decimal = unserialize($cachedValue); // payload missing the 'string' key
// ValueError: Ramsey\Uuid\Type\Decimal::__unserialize(): Argument #1 ($data) is invalid

// after: cache the scalar and rebuild the value object on read
$decimal = new Decimal($cachedValue); // $cachedValue = '1234.50'
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the payload shape before trusting it, then reconstruct
$decoded = unserialize($cached, ['allowed_classes' => false]);
if (!is_string($decoded) && !(is_array($decoded) && isset($decoded['string']))) {
    // treat as cache miss and rebuild
    $decimal = new Decimal($fallbackValue);
}

Try / catch

use Ramsey\Uuid\Type\Decimal;

try {
    $decimal = unserialize($cached);
} catch (\ValueError $e) {
    // malformed payload: treat as a cache miss and rebuild
    $decimal = new Decimal($freshValue);
}

Prevention

When it happens

Trigger: unserialize() of a stored/cached Decimal payload whose array body lacks 'string' — e.g. hand-assembled serialized strings, cache entries written by a different serialization scheme, or partial payloads returned after unserialize() with allowed_classes restrictions reshapes data.

Common situations: Redis/session/cache values written by an older application version or a different library; corrupted cache after crashes; cross-system payload exchange where the producer serializes a different array shape; tests feeding literal serialized strings.

Related errors


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