{"record":{"id":"e9cc75bd2c467922","repo":"clockworklabs/SpacetimeDB","slug":"error-skipping-schedule-registration-for-table","errorCode":null,"errorMessage":"ERROR: Skipping schedule registration for table '%s' because circular reference error is set\n","messagePattern":"ERROR: Skipping schedule registration for table '(.+?)' because circular reference error is set\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h","lineNumber":616,"sourceCode":"            }(std::make_index_sequence<traits::arity - 1>{}, params, param_names, type_reg);\n        }\n\n        RawProcedureDefV10 procedure_def{\n            procedure_name,\n            std::move(params),\n            return_type,\n            FunctionVisibility::ClientCallable,\n        };\n        UpsertProcedure(procedure_def);\n    }\n\n    void RegisterHttpHandlerDef(const std::string& handler_name);\n    void RegisterHttpRoute(const RawHttpRouteDefV10& route);\n    void RegisterHttpRouter(const ::SpacetimeDB::Router& router);\n\n    void RegisterSchedule(const std::string& table_name, uint16_t scheduled_at_column, const std::string& reducer_name) {\n        if (g_circular_ref_error) {\n            std::fprintf(stderr, \"ERROR: Skipping schedule registration for table '%s' because circular reference error is set\\n\",\n                        table_name.c_str());\n            return;\n        }\n        std::optional<std::string> schedule_name = table_name + \"_sched\";\n        auto it = std::find_if(schedules_.begin(), schedules_.end(), [&](const auto& schedule) {\n            return schedule.table_name == table_name;\n        });\n        RawScheduleDefV10 schedule{schedule_name, table_name, scheduled_at_column, reducer_name};\n        if (it == schedules_.end()) {\n            schedules_.push_back(std::move(schedule));\n        } else {\n            *it = std::move(schedule);\n        }\n    }\n\n    void RegisterRowLevelSecurity(const std::string& sql_query) {\n        row_level_security_.push_back(RawRowLevelSecurityDefV9{sql_query});\n    }","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h#L598-L634","documentation":"The V10 builder skips schedule registration (RegisterSchedule, wired from the scheduled-table macro in table_with_constraints.h) because g_circular_ref_error is set — a type cycle was detected during type building. Without this registration the table's scheduled_at column and its associated reducer are never linked, and preinit_99 will fail the module anyway. The schedule itself is fine; the circular type reference elsewhere in the module is the defect.","triggerScenarios":"A table declared with the scheduled clause (RegisterSchedule(table_name, scheduled_at_column, reducer_name)) exists in a module whose row types contain a cycle. During static init, type registration runs first and sets the global flag; the schedule registration for that table is then printed and skipped.","commonSituations":"Adding a scheduled table to a schema that already had a recursive struct; cron-style reducers whose payload types were refactored into mutual references; bindings upgrades reordering registration so the flag is set before schedules are registered.","solutions":["Break the type cycle shown in the '[CIRCULAR REFERENCE DETECTED]' stderr block","Re-examine scheduled-table row types and their nested members for self-reference","Rebuild and confirm the schedule (table_name + '_sched') appears in the module definition","Note the whole module shares one flag — fixing one cycle re-enables all skipped registrations"],"exampleFix":"// before — recursive row type blocks schedule registration\nstruct Job { uint64_t id; std::optional<Job> parent_job; };\n// (table declared scheduled)\n// after\nstruct Job { uint64_t id; std::optional<uint64_t> parent_job_id; };","handlingStrategy":"validation","validationCode":"#include <spacetimedb/internal/module_type_registration.h>\nTEST(Module, SchedulesRegistered) {\n    EXPECT_FALSE(SpacetimeDB::Internal::g_circular_ref_error);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep scheduled-table row types acyclic","After publish, confirm the '<table>_sched' schedule exists before relying on recurring execution","One cycle suppresses schedules, reducers, views and indexes alike — fix it at the type level"],"tags":["spacetimedb","cpp","scheduled-table","circular-reference","schema","static-initialization"],"backgroundTag":"circular-type-reference","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}