{"record":{"id":"ff6a64ae9d7c9957","repo":"ramsey/uuid","slug":"e-getmessage-ff6a64","errorCode":null,"errorMessage":"$e->getMessage()","messagePattern":"\\$e->getMessage\\(\\)","errorType":"exception","errorClass":"UnableToBuildUuidException","httpStatus":null,"severity":"error","filePath":"src/Rfc4122/UuidBuilder.php","lineNumber":108,"sourceCode":"                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_RANDOM => new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_HASH_SHA1 => new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter),\n                Uuid::UUID_TYPE_REORDERED_TIME\n                    /** @phpstan-ignore possiblyImpure.new */\n                    => new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter),\n                Uuid::UUID_TYPE_UNIX_TIME\n                    /** @phpstan-ignore possiblyImpure.new */\n                    => new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter),\n                /** @phpstan-ignore possiblyImpure.new */\n                Uuid::UUID_TYPE_CUSTOM => new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter),\n                default => throw new UnsupportedOperationException(\n                    'The UUID version in the given fields is not supported by this UUID builder',\n                ),\n            };\n        } catch (Throwable $e) {\n            /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */\n            throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e);\n        }\n    }\n\n    /**\n     * Proxy method to allow injecting a mock for testing\n     *\n     * @pure\n     */\n    protected function buildFields(string $bytes): FieldsInterface\n    {\n        /** @phpstan-ignore possiblyImpure.new */\n        return new Fields($bytes);\n    }\n}\n","sourceCodeStart":90,"sourceCodeEnd":123,"githubUrl":"https://github.com/ramsey/uuid/blob/da5b521600a707d2dd097598464bd3090de850f5/src/Rfc4122/UuidBuilder.php#L90-L123","documentation":"Rfc4122\\UuidBuilder::build() wraps its entire body in try/catch (Throwable) and rethrows UnableToBuildUuidException with the original's message, code, and previous-chain. It is the umbrella exception for Uuid::fromString()/fromBytes() and codec decode paths: any fields-validation failure (wrong length, non-RFC variant, invalid version) or constructor failure surfaces as this type carrying the underlying message. Because Uuid::fromString() is lazy, the throw may happen later, when the LazyUuidFromString first unwraps.","triggerScenarios":"Uuid::fromString('12345678-1234-4fff-ffff-123456789abc') (bad variant), a version nibble of 0/9-f, or any decode where Fields' constructor rejects the bytes — the visible exception is UnableToBuildUuidException whose message is the wrapped InvalidArgumentException text. Also triggered by custom codecs feeding malformed bytes to the builder.","commonSituations":"Parsing user-supplied or log-derived UUID strings; accepting IDs from partner systems with non-RFC variants; hex-only validation (Uuid::isValid) passing values that still fail semantic checks.","solutions":["Inspect getPrevious() (and the message) to find the real cause: byte length, variant, or version","Validate variant and version nibbles before parsing when input is untrusted","Catch UnableToBuildUuidException at the parse boundary and convert to your domain's invalid-identifier error"],"exampleFix":"// before\n$uuid = \\Ramsey\\Uuid\\Uuid::fromString($input);\n\n// after\ntry {\n    $uuid = \\Ramsey\\Uuid\\Uuid::fromString($input);\n} catch (\\Ramsey\\Uuid\\Exception\\UnableToBuildUuidException $e) {\n    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();\n    throw new \\InvalidArgumentException(\"Invalid UUID '{$input}': {$reason}\", 0, $e);\n}","handlingStrategy":"try-catch","validationCode":"$hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $input));\nif (strlen($hex) !== 32\n    || !in_array($hex[16], ['8', '9', 'a', 'b'], true)\n    || !in_array(hexdec($hex[12]), range(1, 8), true)) {\n    throw new InvalidArgumentException('Not a valid RFC 9562 UUID');\n}\n$uuid = \\Ramsey\\Uuid\\Uuid::fromString($input);","typeGuard":"function isParsableRfc4122Uuid(string $input): bool\n{\n    $hex = strtolower(preg_replace('/^urn:uuid:|[^0-9a-f]/i', '', $input));\n    return strlen($hex) === 32\n        && in_array($hex[16], ['8', '9', 'a', 'b'], true)\n        && (hexdec($hex[12]) >= 1 && hexdec($hex[12]) <= 8);\n}","tryCatchPattern":"try {\n    $uuid = \\Ramsey\\Uuid\\Uuid::fromString($input);\n} catch (\\Ramsey\\Uuid\\Exception\\UnableToBuildUuidException $e) {\n    throw new DomainIdentifierInvalid($input, $e->getPrevious()?->getMessage() ?? $e->getMessage(), 0, $e);\n}","preventionTips":["Catch this type wherever UUID strings cross a trust boundary","Read getPrevious() to distinguish length vs variant vs version failures","Remember lazy parsing: the throw may occur at first use, not at fromString()"],"tags":["php","ramsey-uuid","uuid-builder","parsing","wrapper-exception","untrusted-input"],"backgroundTag":"uuid-parse-validation-failed","analyzedSha":"da5b521600a707d2dd097598464bd3090de850f5","analyzedAt":"2026-08-21T01:35:29.252Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}