{"record":{"id":"651d44f11dc17f60","repo":"clockworklabs/SpacetimeDB","slug":"uuid-v4-requires-16-bytes","errorCode":null,"errorMessage":"UUID v4 requires 16 bytes","messagePattern":"UUID v4 requires 16 bytes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/lib/uuid.ts","lineNumber":103,"sourceCode":"   * This method assumes the bytes are already sufficiently random.\n   * It only sets the appropriate bits for the UUID version and variant.\n   *\n   * @param bytes - Exactly 16 random bytes\n   * @returns A UUID `v4`\n   * @throws {Error} If `bytes.length !== 16`\n   *\n   * @example\n   * ```ts\n   * const randomBytes = new Uint8Array(16);\n   * const uuid = Uuid.fromRandomBytesV4(randomBytes);\n   *\n   * console.assert(\n   *   uuid.toString() === \"00000000-0000-4000-8000-000000000000\"\n   * );\n   * ```\n   */\n  static fromRandomBytesV4(bytes: Uint8Array): Uuid {\n    if (bytes.length !== 16) throw new Error('UUID v4 requires 16 bytes');\n    const arr = new Uint8Array(bytes);\n    arr[6] = (arr[6] & 0x0f) | 0x40; // version 4\n    arr[8] = (arr[8] & 0x3f) | 0x80; // variant\n    return new Uuid(Uuid.bytesToBigInt(arr));\n  }\n\n  /**\n   * Generate a UUID `v7` using a monotonic counter from `0` to `2^31 - 1`,\n   * a timestamp, and 4 random bytes.\n   *\n   * The counter wraps around on overflow.\n   *\n   * The UUID `v7` is structured as follows:\n   *\n   * ```ascii\n   * ┌───────────────────────────────────────────────┬───────────────────┐\n   * | B0  | B1  | B2  | B3  | B4  | B5              |         B6        |\n   * ├───────────────────────────────────────────────┼───────────────────┤","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/lib/uuid.ts#L85-L121","documentation":"Uuid.fromRandomBytesV4(bytes) builds a version-4 UUID from caller-supplied entropy: it copies the input, then sets the version-4 bits in byte 6 and the variant bits in byte 8. It requires exactly 16 bytes; any other length throws before any bits are touched.","triggerScenarios":"Passing crypto.getRandomValues(new Uint8Array(32)) (code written for 256-bit ids), a hex-decoded string of the wrong length, or a subarray sliced with wrong bounds.","commonSituations":"Reusing random-generation code from another id system; decoding UUID hex strings incorrectly; off-by-one slices of an entropy buffer.","solutions":["Request exactly 16 bytes: crypto.getRandomValues(new Uint8Array(16))","Validate bytes.length === 16 before calling","Or use the library's own generator (e.g. Uuid.generateV4()) instead of supplying bytes"],"exampleFix":"// before\nconst id = Uuid.fromRandomBytesV4(crypto.getRandomValues(new Uint8Array(32))); // -> throws\n\n// after\nconst id = Uuid.fromRandomBytesV4(crypto.getRandomValues(new Uint8Array(16)));","handlingStrategy":"validation","validationCode":"function isUuidV4Entropy(bytes: Uint8Array): boolean {\n  return bytes.length === 16;\n}\n// if (!isUuidV4Entropy(bytes)) throw new TypeError(`expected 16 bytes, got ${bytes.length}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Allocate exactly 16 bytes for v4 entropy: new Uint8Array(16)","Prefer the library's own v4 generator unless you control entropy for a reason","Double-check byte counts when adapting random-generation code from other id systems"],"tags":["uuid","bytes","crypto","validation","javascript"],"backgroundTag":"uuid-byte-length-invalid","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}