clockworklabs/SpacetimeDB · error

ERROR: Enum '%s' did not register as a complex type\n

Error message

ERROR: Enum '%s' did not register as a complex type\n

What it means

Invariant violation in ModuleTypeRegistration::registerAndGetIndex: for an enum, registerType is expected to return a Ref (typespace index) but returned some other AlgebraicType tag. This happens when the registration path degenerates - e.g. an error state was already set (registerType returns a dummy U8), or the enum's bsatn type was not treated as a complex Sum type (missing/incorrect enum serialization annotation, or a name collision resolving to a primitive). Note the function then returns index 0, which silently aliases whatever type occupies typespace slot 0.

Source

Thrown at crates/bindings-cpp/src/internal/module_type_registration.cpp:198

                                                 const std::type_info* cpp_type) {
    // Check if already registered in cache
    auto cache_it = type_name_cache_.find(type_name);
    if (cache_it != type_name_cache_.end()) {
        return cache_it->second;
    }
    
    // Register the type and get the Internal::AlgebraicType result
    AlgebraicType result = registerType(bsatn_type, type_name, cpp_type);
    
    // If it's a Ref, return the index
    if (result.get_tag() == AlgebraicType::Tag::Ref) {
        uint32_t index = result.get<0>();
        type_name_cache_[type_name] = index;
        return index;
    }
    
    // This shouldn't happen for enums - they should always register as complex types
    fprintf(stderr, "ERROR: Enum '%s' did not register as a complex type\n", type_name.c_str());
    return 0;
}

void ModuleTypeRegistration::registerTypeByName(const std::string& type_name, 
                                            const bsatn::AlgebraicType& algebraic_type,
                                            [[maybe_unused]] const std::type_info* cpp_type) {
    // Check if already registered in cache
    auto cache_it = type_name_cache_.find(type_name);
    if (cache_it != type_name_cache_.end()) {
        return;
    }
    
    // Check if already registered in module's types array
    for (const auto& type_def : getV10Builder().GetTypeDefs()) {
        if (type_def.source_name.source_name == type_name) {
            uint32_t typespace_index = type_def.ty;
            type_name_cache_[type_name] = typespace_index;
            return;

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Check for earlier registration errors first - if hasError() is set the dummy type causes this; fix the original error
  2. Ensure the enum uses the SpacetimeDB enum registration/serialization macro so its bsatn type is a proper Sum with named variants
  3. Rename the enum if its name collides with a previously registered primitive, special, or identically named complex type
  4. If it persists with a well-formed enum, capture the type name and report it as a bindings-cpp bug

Example fix

// before
enum class Status { Ok, Err }; // no SpacetimeDB enum registration

// after
// use the provided enum registration so bsatn yields a Sum type
SPACETIMEDB_ENUM(Status, Ok, Err);
Defensive patterns

Strategy: validation

Validate before calling

// before registering enums, ensure no error state is pending
// if (getModuleTypeRegistration().hasError()) { /* fix root cause first */ }

Prevention

When it happens

Trigger: Registering an enum while a previous registration error set has_error_ (dummy U8 returned instead of a Ref); an enum type whose bsatn representation is not a Sum because the enum macro/serialization support was not applied; an enum name that collides with an already-registered primitive or special type.

Common situations: Defining enums used as table columns without the proper SpacetimeDB enum macros for the toolchain; mixing manually-registered types (registerTypeByName) with enum registration using identical names; ignoring an earlier registration error and continuing to register enums.

Related errors


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