clockworklabs/SpacetimeDB · error · Error

Invalid hex UUID

Error message

Invalid hex UUID

What it means

Uuid.parse strips every '-' character and then requires exactly 32 remaining characters. The error fires on wrong length (not on non-hex characters: a 32-character string with invalid hex slips past this check and fails later inside BigInt parsing). Dashes are optional but the total hex digit count must be 32.

Source

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

  /**
   * Parse a UUID from a string representation.
   *
   * @param s - UUID string
   * @returns Parsed UUID
   * @throws {Error} If the string is not a valid UUID
   *
   * @example
   * ```ts
   * const s = "01888d6e-5c00-7000-8000-000000000000";
   * const uuid = Uuid.parse(s);
   *
   * console.assert(uuid.toString() === s);
   * ```
   */
  static parse(s: string): Uuid {
    const hex = s.replace(/-/g, '');
    if (hex.length !== 32) throw new Error('Invalid hex UUID');

    let v = 0n;
    for (let i = 0; i < 32; i += 2) {
      v = (v << 8n) | BigInt(parseInt(hex.slice(i, i + 2), 16));
    }
    return new Uuid(v);
  }

  /** Convert to hex string without a 0x prefix. */
  toHexString(): string {
    return u128ToHexString(this.asBigInt());
  }

  /** Convert to string (hyphenated form). */
  toString(): string {
    const hex = this.toHexString();

    // Format as 8-4-4-4-12

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Normalize before parsing: trim whitespace and strip '{', '}' and any 'urn:uuid:' prefix
  2. Validate with a UUID regex before calling Uuid.parse
  3. If the string came from Uuid.toString(), pass it through unchanged - it is already 8-4-4-4-12

Example fix

// before
const uuid = Uuid.parse('{01888d6e-5c00-7000-8000-000000000000}'); // throws

// after
const s = '{01888d6e-5c00-7000-8000-000000000000}'.replace(/[{}]/g, '').replace(/^urn:uuid:/i, '').trim();
const uuid = UUID_RE.test(s) ? Uuid.parse(s) : null;
Defensive patterns

Strategy: type-guard

Validate before calling

const s = raw.replace(/[{}\s]/g, '').replace(/^urn:uuid:/i, '');
if (!isUuidString(s)) throw new TypeError('not a UUID string');
const uuid = Uuid.parse(s);

Type guard

const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
function isUuidString(s: unknown): s is string {
  return typeof s === 'string' && (UUID_RE.test(s) || /^[0-9a-fA-F]{32}$/.test(s));
}

Try / catch

try {
  const id = Uuid.parse(input);
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid hex UUID') {
    // treat as malformed external input: reject or skip the record
  } else throw e;
}

Prevention

When it happens

Trigger: Parsing strings such as '{01888d6e-5c00-7000-8000-000000000000}' (braces), 'urn:uuid:...' (URN prefix), a truncated UUID, a UUID with whitespace, or one with extra/missing hex digits.

Common situations: Copying a UUID from logs together with quotes or braces; receiving ids wrapped by another system (PostgreSQL URN output, JSON with padding); a typo dropping a character; concatenated strings.

Related errors


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