clockworklabs/SpacetimeDB · error

ERROR: Skipping default-value registration '%s.%s' because c

Error message

ERROR: Skipping default-value registration '%s.%s' because circular reference error is set

What it means

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.

Source

Thrown at crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h:260

                    "table='" + table_name + "' index='" + index_name + "' field='" + field_name + "' was not found");
                return;
            }
        }

        std::string generated_name = table_name + "_" + field_names[0];
        for (size_t i = 1; i < field_names.size(); ++i) {
            generated_name += "_" + field_names[i];
        }
        generated_name += "_idx_btree";
        table_it->indexes.push_back(CreateBTreeIndex(table_name, generated_name, field_indexes, index_name));
    }

    template<typename T>
    void AddColumnDefault(const std::string& table_name,
                          const std::string& field_name,
                          const std::vector<uint8_t>& serialized_value) {
        if (g_circular_ref_error) {
            std::fprintf(stderr, "ERROR: Skipping default-value registration '%s.%s' because circular reference error is set\n",
                        table_name.c_str(), field_name.c_str());
            return;
        }
        auto table_it = FindTable(table_name);
        if (table_it == tables_.end()) {
            SetConstraintRegistrationError(
                "TABLE_NOT_FOUND",
                "table='" + table_name + "' default field='" + field_name + "' references an unknown table");
            return;
        }

        SpacetimeDB::field_registrar<T>::register_fields();
        auto& descriptor_map = SpacetimeDB::get_table_descriptors();
        auto it = descriptor_map.find(&typeid(T));
        if (it == descriptor_map.end()) {
            SetConstraintRegistrationError(
                "NO_FIELD_DESCRIPTORS",
                "table='" + table_name + "' default field='" + field_name + "' has no registered field descriptors");

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Find the '[CIRCULAR REFERENCE DETECTED]' block earlier in stderr; it names the type and shows the chain (e.g. A -> B -> A)
  2. Remove the cycle by storing IDs/indices instead of embedded values in the offending type
  3. Rebuild — once g_circular_ref_error is never set, this message goes away and the default registers normally
  4. Verify the rebuilt module publishes and the column default appears in the schema (describe the table after publish)

Example fix

// before — cycle + default: default registration skipped
struct Config {
    uint64_t id;
    std::optional<Config> parent;   // cycle: Config -> Config
};
// after
struct Config {
    uint64_t id;
    std::optional<uint64_t> parent_id;   // acyclic; default value now registers
};
Defensive patterns

Strategy: validation

Validate before calling

// After module static init (e.g. in a test binary):
#include <spacetimedb/internal/module_type_registration.h>
ASSERT_FALSE(SpacetimeDB::Internal::g_circular_ref_error) << "fix the type cycle before trusting column defaults";

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/74e183a404cc909b. Report an issue: GitHub.