ramsey/uuid · error · InvalidArgumentException

Fields used to create a UuidV4 must represent a version 4 (r

Error message

Fields used to create a UuidV4 must represent a version 4 (random) UUID

What it means

Ramsey\Uuid\Rfc4122\UuidV4 wraps a field set that must represent a version 4 (random) UUID. The constructor checks $fields->getVersion() against Uuid::UUID_TYPE_RANDOM (4) and throws Ramsey\Uuid\Exception\InvalidArgumentException otherwise. The guard guarantees that anything typed UuidV4 truly carries randomly generated bits with the version nibble set to 4. Only advanced code (custom builders, codecs) should ever hit this constructor.

Source

Thrown at src/Rfc4122/UuidV4.php:49

final class UuidV4 extends Uuid implements UuidInterface
{
    /**
     * Creates a version 4 (random) UUID
     *
     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID
     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers
     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings
     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a
     *     UUID to unix timestamps
     */
    public function __construct(
        Rfc4122FieldsInterface $fields,
        NumberConverterInterface $numberConverter,
        CodecInterface $codec,
        TimeConverterInterface $timeConverter,
    ) {
        if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) {
            throw new InvalidArgumentException(
                'Fields used to create a UuidV4 must represent a version 4 (random) UUID',
            );
        }

        parent::__construct($fields, $numberConverter, $codec, $timeConverter);
    }
}

View on GitHub (pinned to da5b521600)

Solutions

  1. Use Uuid::uuid4() to generate random v4 UUIDs instead of constructing UuidV4 manually
  2. Use Uuid::fromString($string) / Uuid::fromBytes($bytes) for existing values — they never throw version-mismatch errors
  3. Check $fields->getVersion() === Uuid::UUID_TYPE_RANDOM before constructing UuidV4 directly
  4. In custom builders, branch on getVersion() and only instantiate UuidV4 for version 4 bytes

Example fix

// before: $bytes came from a version 7 UUID, but the code hardcodes UuidV4
$uuid = new UuidV4(new Fields($bytes), $numberConverter, $codec, $timeConverter);
// InvalidArgumentException: Fields used to create a UuidV4 must represent a version 4 (random) UUID

// after: build from the bytes without assuming the version
$uuid = Uuid::fromBytes($bytes); // returns UuidV7 for these bytes

// or generate a fresh random v4
$uuid = Uuid::uuid4();
Defensive patterns

Strategy: validation

Validate before calling

use Ramsey\Uuid\Rfc4122\FieldsInterface;
use Ramsey\Uuid\Uuid;

// Run before constructing UuidV4
if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) {
    throw new \InvalidArgumentException(
        'Cannot build UuidV4 from version ' . $fields->getVersion() . ' fields'
    );
}

Type guard

use Ramsey\Uuid\Rfc4122\FieldsInterface;
use Ramsey\Uuid\Rfc4122\UuidV4;
use Ramsey\Uuid\Uuid;

function isVersion4Fields(FieldsInterface $fields): bool
{
    return $fields->getVersion() === Uuid::UUID_TYPE_RANDOM;
}

$uuid = Uuid::fromBytes($bytes);
$isRandom = $uuid instanceof UuidV4;

Try / catch

use Ramsey\Uuid\Exception\InvalidArgumentException;

try {
    $uuid = new UuidV4($fields, $numberConverter, $codec, $timeConverter);
} catch (InvalidArgumentException $e) {
    $uuid = new Ramsey\Uuid\Uuid($fields, $numberConverter, $codec, $timeConverter);
}

Prevention

When it happens

Trigger: Calling new UuidV4($fields, $numberConverter, $codec, $timeConverter) with fields whose version nibble is not 4 — e.g. fields built from a v1 time-based UUID's bytes, or from a v7 UUID. Also a custom codec/builder that always maps decoded UUIDs to UuidV4.

Common situations: Code that decodes arbitrary UUID bytes and hardcodes new UuidV4(...) assuming random UUIDs; upgrading a system that previously stored v1 UUIDs while the wrapping code still expects v4; test doubles that build fields from fixed byte strings with a stale version nibble.

Related errors


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