clockworklabs/SpacetimeDB · error · Error

UUID v4 requires 16 bytes

Error message

UUID v4 requires 16 bytes

What it means

Same scheduled-table validation, but this branch fires when a primary-key column exists while the scheduled_at column does not: neither a field named scheduled_at nor any column named by scheduled(reducer, at = custom) was found among the struct fields. The error offers both fixes — add the default column or declare a custom one via at = ...

Solutions

  1. Add the field: scheduled_at: spacetimedb::ScheduleAt,
  2. For a custom name: #[spacetimedb::table(scheduled = my_reducer, at = run_at)] plus a run_at: spacetimedb::ScheduleAt field.
  3. Ensure the type is exactly spacetimedb::ScheduleAt.

Example fix

// before
#[spacetimedb::table(accessor = job, scheduled = run)]
pub struct Job {
    #[primary_key] #[auto_inc] scheduled_id: u64,
    pub payload: String,
}

// after (custom column name)
#[spacetimedb::table(accessor = job, scheduled = run, at = run_at)]
pub struct Job {
    #[primary_key] #[auto_inc] scheduled_id: u64,
    pub run_at: spacetimedb::ScheduleAt,
    pub payload: String,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A scheduled table that has the #[primary_key]/#[auto_inc] scheduled_id column but no scheduled_at: spacetimedb::ScheduleAt field, or whose at = custom_at argument names a field that does not exist.

Common situations: Renaming scheduled_at without adding at = ...; deleting the column during a refactor; a typo in the at = ... value.

Related errors


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

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