clockworklabs/SpacetimeDB · error · TypeError

Schedule target table is not part of this schema.

Error message

Schedule target table is not part of this schema.

What it means

During `resolveSchedules`, each pending schedule must be tied to a table that is part of the schema. If neither an explicit name was supplied nor the table object found in `tableSourceNames`, the schedule target is unknown to this schema and the build fails with 'Schedule target table is not part of this schema.' The scheduled reducer/procedure's payload table must appear in the object passed to `schema({...})`.

Solutions

  1. Add the schedule target table to the schema entries: `export default schema({ scheduledMessages, ... })` using the same handle you passed to `onSchedule`.
  2. Ensure the table handle passed to `onSchedule` is the very same object registered in the schema (identity matters, not just an identical row shape).
  3. If the table comes from a shared library, import that library's table handle and register it once in this schema.

Example fix

// before
const scheduledMessages = table({}, row);
const processMsg = spacetimedb.reducer(
  { onSchedule: scheduledMessages }, {...}, handler
);
export default schema({ users }); // scheduledMessages missing

// after
export default schema({ users, scheduledMessages });
Defensive patterns

Strategy: validation

Validate before calling

// Dev-time: every onSchedule table must also be a schema entry.
const schemaTables = new Set<unknown>([users, orders, scheduledMessages]);
function onScheduleTableIsRegistered(t: unknown) {
  if (!schemaTables.has(t)) throw new Error('schedule table missing from schema entries');
}
// spacetimedb.reducer({ onSchedule: scheduledMessages }, ...); with scheduledMessages in the set

Prevention

When it happens

Trigger: Calling `spacetimedb.reducer({ onSchedule: someTable }, ...)` where `someTable` was created with `table()` but not listed in the schema entries object; defining the scheduled table in a different schema instance; passing a table-like object that was never registered.

Common situations: Extracting scheduled reducers into a library file while the table lives (unregistered) in another module; forgetting to add the new schedule table to the schema entries after introducing a scheduled reducer; renaming the schema entry so the mapping is lost.

Related errors


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

Appendix: source

Thrown at crates/bindings-typescript/src/server/schema.ts:171

    for (const {
      functionName: knownFunctionName,
      reducer,
      table,
      tableName: knownTableName,
      scheduleAtCol: knownScheduleAtCol,
    } of this.pendingSchedules) {
      let tableName = knownTableName;
      if (tableName === undefined) {
        const tableNames = this.tableSourceNames.get(table);
        if (tableNames !== undefined && tableNames.length > 1) {
          throw new TypeError(
            'Schedule target table is registered more than once in this schema. Use a distinct table handle for each scheduled table.'
          );
        }
        tableName = tableNames?.[0];
      }
      if (tableName === undefined) {
        throw new TypeError(
          'Schedule target table is not part of this schema.'
        );
      }

      const scheduleAtCol = knownScheduleAtCol ?? table.scheduleAtCol;
      if (scheduleAtCol === undefined) {
        throw new TypeError(
          `Table ${tableName} defines a schedule, but it does not have a ScheduleAt column.`
        );
      }

      const functionName =
        knownFunctionName ??
        (reducer === undefined
          ? undefined
          : this.functionExports.get(reducer()));
      if (functionName === undefined) {
        const msg = `Table ${tableName} defines a schedule, but it seems like the associated function was not exported.`;

View on GitHub (pinned to eddf9f5014)