{"record":{"id":"74e183a404cc909b","repo":"clockworklabs/SpacetimeDB","slug":"error-skipping-default-value-registration-s-s","errorCode":null,"errorMessage":"ERROR: Skipping default-value registration '%s.%s' because circular reference error is set\n","messagePattern":"ERROR: Skipping default-value registration '(.+?)\\.(.+?)' 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":260,"sourceCode":"                    \"table='\" + table_name + \"' index='\" + index_name + \"' field='\" + field_name + \"' was not found\");\n                return;\n            }\n        }\n\n        std::string generated_name = table_name + \"_\" + field_names[0];\n        for (size_t i = 1; i < field_names.size(); ++i) {\n            generated_name += \"_\" + field_names[i];\n        }\n        generated_name += \"_idx_btree\";\n        table_it->indexes.push_back(CreateBTreeIndex(table_name, generated_name, field_indexes, index_name));\n    }\n\n    template<typename T>\n    void AddColumnDefault(const std::string& table_name,\n                          const std::string& field_name,\n                          const std::vector<uint8_t>& serialized_value) {\n        if (g_circular_ref_error) {\n            std::fprintf(stderr, \"ERROR: Skipping default-value registration '%s.%s' because circular reference error is set\\n\",\n                        table_name.c_str(), field_name.c_str());\n            return;\n        }\n        auto table_it = FindTable(table_name);\n        if (table_it == tables_.end()) {\n            SetConstraintRegistrationError(\n                \"TABLE_NOT_FOUND\",\n                \"table='\" + table_name + \"' default field='\" + field_name + \"' references an unknown table\");\n            return;\n        }\n\n        SpacetimeDB::field_registrar<T>::register_fields();\n        auto& descriptor_map = SpacetimeDB::get_table_descriptors();\n        auto it = descriptor_map.find(&typeid(T));\n        if (it == descriptor_map.end()) {\n            SetConstraintRegistrationError(\n                \"NO_FIELD_DESCRIPTORS\",\n                \"table='\" + table_name + \"' default field='\" + field_name + \"' has no registered field descriptors\");","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h#L242-L278","documentation":"The V10 builder refuses to register a column default value (AddColumnDefault) because g_circular_ref_error is already set from an earlier type-registration cycle. The skip protects the builder from stacking registrations onto a module whose type graph is known-broken; the underlying circular-reference error is reported separately and preinit_99 will fail the module. Treat this line as a symptom, not the root cause.","triggerScenarios":"A row type in a cycle (directly or transitively) is used on a table whose macro also declares a column default (ST_COLUMN_DEFAULT / AddColumnDefault with a serialized BSATN value). Type registration runs first during static init, sets the flag, and this default-value registration for '<table>.<field>' is then dropped.","commonSituations":"Adding a default clause to a table whose row type embeds itself (linked-list node, hierarchy node); introducing a new cross-referencing type pair while defaults already existed; version upgrades that change when/where type registration happens so a previously latent cycle gets detected.","solutions":["Find the '[CIRCULAR REFERENCE DETECTED]' block earlier in stderr; it names the type and shows the chain (e.g. A -> B -> A)","Remove the cycle by storing IDs/indices instead of embedded values in the offending type","Rebuild — once g_circular_ref_error is never set, this message goes away and the default registers normally","Verify the rebuilt module publishes and the column default appears in the schema (describe the table after publish)"],"exampleFix":"// before — cycle + default: default registration skipped\nstruct Config {\n    uint64_t id;\n    std::optional<Config> parent;   // cycle: Config -> Config\n};\n// after\nstruct Config {\n    uint64_t id;\n    std::optional<uint64_t> parent_id;   // acyclic; default value now registers\n};","handlingStrategy":"validation","validationCode":"// After module static init (e.g. in a test binary):\n#include <spacetimedb/internal/module_type_registration.h>\nASSERT_FALSE(SpacetimeDB::Internal::g_circular_ref_error) << \"fix the type cycle before trusting column defaults\";","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Model relationships with ID references, not embedded values","Run a schema smoke test after adding any column default so silent skips fail CI","Verify published schema (describe the table) rather than assuming the default was applied"],"tags":["spacetimedb","cpp","schema","circular-reference","column-default","static-initialization"],"backgroundTag":"circular-type-reference","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}