clockworklabs/SpacetimeDB · error
Original error: Multiple primary keys detected in table '%s'
Error message
Original error: Multiple primary keys detected in table '%s'
What it means
Detail line of the '[CONSTRAINT ERROR]' banner (error 666) that restates the root cause: multiple primary keys were detected in the named table (g_multiple_primary_key_table_name). It exists so the module-side stderr log carries the table name, since the server only sees the opaque ERROR_MULTIPLE_PRIMARY_KEYS_<table> error type.
Source
Thrown at crates/bindings-cpp/src/internal/Module.cpp:263
// Create the error type name
std::string error_type_name = "ERROR_MULTIPLE_PRIMARY_KEYS_" + g_multiple_primary_key_table_name;
// Add a single named type export that points to a non-existent typespace index
// This will cause SpacetimeDB to error when it tries to resolve the type
RawTypeDefV10 error_type;
error_type.source_name.scope = {};
error_type.source_name.source_name = error_type_name;
error_type.ty = 999999; // Invalid typespace index - will cause an error
error_type.custom_ordering = false;
getV10Builder().GetTypeDefs().push_back(error_type);
// Don't add anything to the typespace - this ensures the reference is invalid
// The server will fail with an error message that includes our error type name
// Also log to stderr for debugging
fprintf(stderr, "\n[CONSTRAINT ERROR] Module cleared and replaced with error type: %s\n", error_type_name.c_str());
fprintf(stderr, "Original error: Multiple primary keys detected in table '%s'\n\n", g_multiple_primary_key_table_name.c_str());
fflush(stderr);
return; // Exit early, don't check type registration errors
}
if (g_constraint_registration_error) {
getV10Builder().Clear();
std::string error_type_name = "ERROR_CONSTRAINT_REGISTRATION_" + g_constraint_registration_error_code;
for (char& c : error_type_name) {
if (!std::isalnum(c) && c != '_') {
c = '_';
}
}
RawTypeDefV10 error_type;
error_type.source_name.scope = {};
error_type.source_name.source_name = error_type_name;View on GitHub (pinned to 6dee26c6ef)
Solutions
- Open the table named on this line and keep a single FIELD_PrimaryKey/FIELD_PrimaryKeyAutoInc macro
- Convert the surplus primary-key column to FIELD_Unique or part of a multi-column index
- Republish and confirm the ERROR_MULTIPLE_PRIMARY_KEYS_* type no longer appears in the module description
Example fix
// before FIELD_PrimaryKey(Session, id); FIELD_PrimaryKey(Session, token); // after FIELD_PrimaryKey(Session, id); FIELD_Unique(Session, token);
Defensive patterns
Strategy: validation
Prevention
- Search all translation units for primary-key macros on the table named here
- Convert surplus keys to FIELD_Unique or multi-column indexes
- Keep constraints and struct in one place for reviewability
When it happens
Trigger: Emitted together with error 666 whenever __preinit__99_validate_types finds g_multiple_primary_key_error set; the table named here is the one carrying two or more primary-key constraints.
Common situations: Same as error 661/666 - duplicated or composite primary-key macros on one table struct.
Related errors
- ERROR: Multiple primary keys detected in table '%s'
- [CONSTRAINT ERROR] Module cleared and replaced with error t
- Original error: %s
- View '${exportName}' can have at most one primaryKey() colum
- When replaying `st_column` update: `table_primary_key` shoul
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/7b4dea1d575f7050.
Report an issue: GitHub.