clockworklabs/SpacetimeDB · error · Error

UUID v4 requires 16 bytes

Error message

UUID v4 requires 16 bytes

What it means

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.

Source

Thrown at crates/bindings-typescript/src/lib/uuid.ts:103

   * This method assumes the bytes are already sufficiently random.
   * It only sets the appropriate bits for the UUID version and variant.
   *
   * @param bytes - Exactly 16 random bytes
   * @returns A UUID `v4`
   * @throws {Error} If `bytes.length !== 16`
   *
   * @example
   * ```ts
   * const randomBytes = new Uint8Array(16);
   * const uuid = Uuid.fromRandomBytesV4(randomBytes);
   *
   * console.assert(
   *   uuid.toString() === "00000000-0000-4000-8000-000000000000"
   * );
   * ```
   */
  static fromRandomBytesV4(bytes: Uint8Array): Uuid {
    if (bytes.length !== 16) throw new Error('UUID v4 requires 16 bytes');
    const arr = new Uint8Array(bytes);
    arr[6] = (arr[6] & 0x0f) | 0x40; // version 4
    arr[8] = (arr[8] & 0x3f) | 0x80; // variant
    return new Uuid(Uuid.bytesToBigInt(arr));
  }

  /**
   * Generate a UUID `v7` using a monotonic counter from `0` to `2^31 - 1`,
   * a timestamp, and 4 random bytes.
   *
   * The counter wraps around on overflow.
   *
   * The UUID `v7` is structured as follows:
   *
   * ```ascii
   * ┌───────────────────────────────────────────────┬───────────────────┐
   * | B0  | B1  | B2  | B3  | B4  | B5              |         B6        |
   * ├───────────────────────────────────────────────┼───────────────────┤

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Request exactly 16 bytes: crypto.getRandomValues(new Uint8Array(16))
  2. Validate bytes.length === 16 before calling
  3. Or use the library's own generator (e.g. Uuid.generateV4()) instead of supplying bytes

Example fix

// before
const id = Uuid.fromRandomBytesV4(crypto.getRandomValues(new Uint8Array(32))); // -> throws

// after
const id = Uuid.fromRandomBytesV4(crypto.getRandomValues(new Uint8Array(16)));
Defensive patterns

Strategy: validation

Validate before calling

function isUuidV4Entropy(bytes: Uint8Array): boolean {
  return bytes.length === 16;
}
// if (!isUuidV4Entropy(bytes)) throw new TypeError(`expected 16 bytes, got ${bytes.length}`);

Prevention

When it happens

Trigger: 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.

Common situations: Reusing random-generation code from another id system; decoding UUID hex strings incorrectly; off-by-one slices of an entropy buffer.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/651d44f11dc17f60. Report an issue: GitHub.