clockworklabs/SpacetimeDB · warning
ERROR: Failed to register named complex type '%s'\n
Error message
ERROR: Failed to register named complex type '%s'\n
What it means
Warning-level failure log in ModuleTypeRegistration::registerTypeByName: after checking the cache and the module's existing type defs, it registers the named complex type via registerType and expects a Ref back; a non-Ref result means the type did not land in the typespace as a named complex type. Unlike the enum path it does not corrupt an index, but the type is missing from the module description, which can surface later as unresolved types or schema mismatches on the server.
Source
Thrown at crates/bindings-cpp/src/internal/module_type_registration.cpp:224
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;
}
}
// Register by name using the same full-fidelity path as other complex type registration.
// This avoids lossy conversion of nested fields/variants.
auto result = registerType(algebraic_type, type_name, cpp_type);
if (result.get_tag() != AlgebraicType::Tag::Ref) {
fprintf(stderr, "ERROR: Failed to register named complex type '%s'\n", type_name.c_str());
}
}
bool ModuleTypeRegistration::isPrimitive(const bsatn::AlgebraicType& type) const {
auto tag = static_cast<uint32_t>(type.tag());
// Use range check: String (4) to F64 (19) covers all primitive types
return tag >= static_cast<uint32_t>(bsatn::AlgebraicTypeTag::String) &&
tag <= static_cast<uint32_t>(bsatn::AlgebraicTypeTag::F64);
}
bool ModuleTypeRegistration::isSpecialType(const bsatn::AlgebraicType& type) const {
if (type.tag() != bsatn::AlgebraicTypeTag::Product) {
return false;
}
const auto& product = type.as_product();
if (product.elements.size() != 1) {
return false;View on GitHub (pinned to 6dee26c6ef)
Solutions
- Rename the type so it cannot collide with built-in/special type names (Identity, ConnectionId, ScheduleAt spellings)
- Check for and fix any earlier registration error - the has_error_ state makes registerType return non-Ref
- Ensure the algebraic type passed in is genuinely a complex type (Sum/Product), not one that isPrimitive()/isSpecialType() filters out
- Verify the module description after publish contains the named type; if not, restructure the field type (e.g. introduce a dedicated struct)
Example fix
// before: field type name collides with a special type name
struct Event { Identity Identity; }; // named like the special type
// after
struct Event { Identity sender; }; // distinct field/type naming Defensive patterns
Strategy: validation
Prevention
- Avoid naming user types after built-in/special types (Identity, ConnectionId, ScheduleAt)
- Check hasError() after bulk type registration and fix the first failure before continuing
- Verify published module descriptions contain every named type you register
When it happens
Trigger: registerTypeByName called (e.g. from V10Builder::RegisterTable for Sum-typed fields) while an earlier error state is active (dummy U8 returned); the supplied algebraic_type resolves to a primitive or special type (Identity/ConnectionId-shaped products) instead of a complex type; the name is already cached under a different shape.
Common situations: Naming a table's sum-type field identically to a built-in/special type; registering nested variant types while a prior registration already failed; version changes in bindings-cpp altering which types count as 'special'.
Related errors
- [TYPE ERROR] Module cleared and replaced with error type: %
- ERROR: Enum '%s' did not register as a complex type\n
- ERROR: Constraint registration failed [%s] %s
- [CIRCULAR REFERENCE ERROR] Module cleared and replaced with
- Type '%s' contains a circular reference to itself
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/280c676de108ddac.
Report an issue: GitHub.