clockworklabs/SpacetimeDB · error
ERROR: Field %s.%s has primary_key constraint - cannot have
Error message
ERROR: Field %s.%s has primary_key constraint - cannot have default value
What it means
AddColumnDefault enforces the schema rule that a column with a primary_key constraint cannot also have a default value: if the resolved field index appears in table->primary_key, it prints this message (note: without a trailing newline) and drops the default. Primary key values are identity-assigned by the database, so a client-supplied default would conflict with key generation.
Source
Thrown at crates/bindings-cpp/include/spacetimedb/internal/v9_builder.h:645
field_found = true;
break;
}
field_idx++;
}
if (!field_found) {
fprintf(stderr, "ERROR: Field '%s' not found in table '%s'\n",
field_name.c_str(), table_name.c_str());
return;
}
// Validate: default values cannot be used with primary_key, unique, or auto_inc
// Check if this column is in the primary key
for (uint16_t pk_col : table->primary_key) {
if (pk_col == field_idx) {
std::string error_msg = "ERROR: Field " + table_name + "." + field_name +
" has primary_key constraint - cannot have default value";
fprintf(stderr, "%s", error_msg.c_str());
// fprintf(stderr, "ERROR: has primary_key constraint - cannot have default value",
// table_name.c_str(), field_name.c_str());
return;
}
}
// Check if this column has a unique constraint
for (const auto& constraint : table->constraints) {
if (constraint.data.get_tag() == 0) { // Unique constraint variant
const auto& unique_data = constraint.data.get<0>();
if (unique_data.columns.size() == 1 && unique_data.columns[0] == field_idx) {
fprintf(stderr, "ERROR: Field %s.%s has unique constraint - cannot have default value",
table_name.c_str(), field_name.c_str());
return;
}
}
}
View on GitHub (pinned to 524b4487d9)
Solutions
- Remove the column default from the primary key column — keys are generated, not defaulted
- If a specific key value is required, generate it in the init reducer instead of a column default
- Rebuild and confirm no 'primary_key constraint - cannot have default value' message remains
- Audit for the sibling checks (unique, auto_inc) on the same column
Example fix
// before ST_TABLE(user, ...); // id is primary key ST_COLUMN_DEFAULT(user, id, 0); // conflict: pk + default // after ST_TABLE(user, ...); // id is primary key, value assigned by the db // (default removed)
Defensive patterns
Strategy: validation
Validate before calling
// Policy check before adding a default: refuse defaults on pk columns
// (after init, with table resolved and field_idx computed):
for (uint16_t pk : table.primary_key)
if (pk == field_idx) /* skip/forbid the ST_COLUMN_DEFAULT annotation */; Prevention
- Adopt a rule: identity columns (pk/auto_inc/unique) never carry defaults
- Encode the rule in a schema lint step over annotations
- Move seeding logic into the init reducer instead of defaults on keys
When it happens
Trigger: Marking a column both ST_PRIMARY_KEY/#[primary_key] and ST_COLUMN_DEFAULT on the same table; the primary key macro ran first (so table->primary_key is populated) and then AddColumnDefault resolves the same field_idx in that list.
Common situations: Copying a default onto an id column that was later promoted to primary key; schema migrations that add primary_key without removing existing defaults; mismatches between macro ordering making the conflict intermittent between builds.
Related errors
- ERROR: Field %s.%s has unique constraint - cannot have defau
- ERROR: Field %s.%s has auto_inc constraint - cannot have def
- ERROR: Skipping default-value registration '%s.%s' because c
- ERROR: Table '%s' not found for default value on field '%s'
- ERROR: Skipping multi-column index registration '%s.%s' beca
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/5b720d5434c79745.
Report an issue: GitHub.