{"record":{"id":"4c0a5dd86b597ad8","repo":"ramsey/uuid","slug":"fields-used-to-create-a-uuidv4-must-represent-a-ve","errorCode":null,"errorMessage":"Fields used to create a UuidV4 must represent a version 4 (random) UUID","messagePattern":"Fields used to create a UuidV4 must represent a version 4 \\(random\\) UUID","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Rfc4122/UuidV4.php","lineNumber":49,"sourceCode":"final class UuidV4 extends Uuid implements UuidInterface\n{\n    /**\n     * Creates a version 4 (random) UUID\n     *\n     * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID\n     * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers\n     * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings\n     * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a\n     *     UUID to unix timestamps\n     */\n    public function __construct(\n        Rfc4122FieldsInterface $fields,\n        NumberConverterInterface $numberConverter,\n        CodecInterface $codec,\n        TimeConverterInterface $timeConverter,\n    ) {\n        if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) {\n            throw new InvalidArgumentException(\n                'Fields used to create a UuidV4 must represent a version 4 (random) UUID',\n            );\n        }\n\n        parent::__construct($fields, $numberConverter, $codec, $timeConverter);\n    }\n}\n","sourceCodeStart":31,"sourceCodeEnd":57,"githubUrl":"https://github.com/ramsey/uuid/blob/da5b521600a707d2dd097598464bd3090de850f5/src/Rfc4122/UuidV4.php#L31-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use Uuid::uuid4() to generate random v4 UUIDs instead of constructing UuidV4 manually","Use Uuid::fromString($string) / Uuid::fromBytes($bytes) for existing values — they never throw version-mismatch errors","Check $fields->getVersion() === Uuid::UUID_TYPE_RANDOM before constructing UuidV4 directly","In custom builders, branch on getVersion() and only instantiate UuidV4 for version 4 bytes"],"exampleFix":"// before: $bytes came from a version 7 UUID, but the code hardcodes UuidV4\n$uuid = new UuidV4(new Fields($bytes), $numberConverter, $codec, $timeConverter);\n// InvalidArgumentException: Fields used to create a UuidV4 must represent a version 4 (random) UUID\n\n// after: build from the bytes without assuming the version\n$uuid = Uuid::fromBytes($bytes); // returns UuidV7 for these bytes\n\n// or generate a fresh random v4\n$uuid = Uuid::uuid4();","handlingStrategy":"validation","validationCode":"use Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Uuid;\n\n// Run before constructing UuidV4\nif ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) {\n    throw new \\InvalidArgumentException(\n        'Cannot build UuidV4 from version ' . $fields->getVersion() . ' fields'\n    );\n}","typeGuard":"use Ramsey\\Uuid\\Rfc4122\\FieldsInterface;\nuse Ramsey\\Uuid\\Rfc4122\\UuidV4;\nuse Ramsey\\Uuid\\Uuid;\n\nfunction isVersion4Fields(FieldsInterface $fields): bool\n{\n    return $fields->getVersion() === Uuid::UUID_TYPE_RANDOM;\n}\n\n$uuid = Uuid::fromBytes($bytes);\n$isRandom = $uuid instanceof UuidV4;","tryCatchPattern":"use Ramsey\\Uuid\\Exception\\InvalidArgumentException;\n\ntry {\n    $uuid = new UuidV4($fields, $numberConverter, $codec, $timeConverter);\n} catch (InvalidArgumentException $e) {\n    $uuid = new Ramsey\\Uuid\\Uuid($fields, $numberConverter, $codec, $timeConverter);\n}","preventionTips":["Use Uuid::uuid4() for generation and Uuid::fromString()/fromBytes() for wrapping","Do not assume external UUIDs are random v4 — verify with getVersion() or instanceof","In builders, branch on the version nibble instead of hardcoding UuidV4","Keep fixture byte strings' version nibble consistent with the class under test"],"tags":["php","ramsey-uuid","uuid","validation","constructor","version-mismatch","random"],"backgroundTag":"uuid-version-mismatch","analyzedSha":"da5b521600a707d2dd097598464bd3090de850f5","analyzedAt":"2026-08-21T01:35:29.252Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}