clockworklabs/SpacetimeDB · error · Error

Invalid hex UUID

Error message

Invalid hex UUID

What it means

Uuid.parse strips every '-' from the input and then requires the remainder to be exactly 32 characters. The 'Invalid hex UUID' error is this dash-stripped length check: wrong digit count, brace/URN wrappers, 0x prefixes, or extra characters all change the length and fail. Note the parser checks length, not character legality, so do not rely on it to validate hex.

Solutions

  1. Validate with a canonical UUID regex before parsing (see type guard)
  2. Normalize the input first: trim whitespace, strip surrounding braces and 'urn:uuid:' prefixes
  3. Only call parse on values produced by Uuid.toString() or a known UUID source

Example fix

// before
const id = Uuid.parse(rawUserInput); // may throw

// after
const id = isUuidString(rawUserInput) ? Uuid.parse(rawUserInput) : fallbackForInvalidId(rawUserInput);
Defensive patterns

Strategy: type-guard

Validate before calling

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}$/;
if (!UUID_RE.test(candidate)) {
  throw new Error(`not a canonical UUID: ${candidate}`);
}
const id = Uuid.parse(candidate);

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);
}

Try / catch

try {
  const id = Uuid.parse(candidate);
} catch (e) {
  if (e instanceof Error && e.message === 'Invalid hex UUID') {
    // treat as bad input: reject, re-prompt, or skip the record
  }
  throw e;
}

Prevention

When it happens

Trigger: Uuid.parse('not-a-uuid'); Uuid.parse('01888d6e-5c00-7000-8000-0000000000') (31 hex digits after the 12 hex digits of the last group are short by one); strings like '{01888d6e-...}' or 'urn:uuid:...' that add non-hex characters; values with trailing whitespace or a 0x prefix.

Common situations: Forwarding user input, URL query params, or database columns straight into parse; mixing canonical hyphenated and compact 32-char formats; UUIDs received from other systems wrapped in braces or URN prefixes.

Related errors


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

Appendix: 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 6dee26c6ef)