clockworklabs/SpacetimeDB · error
ERROR: Table '%s' not found for default value on field '%s'
Error message
ERROR: Table '%s' not found for default value on field '%s'
What it means
V9Builder::AddColumnDefault resolves the table by name before attaching a serialized default value; when findTableByName finds no match, it prints this and returns, so the column default is silently dropped and the module publishes without it. Inserts that relied on the default will then require an explicit value (or fail), which is often how this is first noticed.
Source
Thrown at crates/bindings-cpp/include/spacetimedb/internal/v9_builder.h:606
index_def.accessor_name = index_name; // User-provided index name for access
index_def.algorithm = algorithm;
// Add to table's indexes
table->indexes.push_back(std::move(index_def));
//fprintf(stdout, "DEBUG: Successfully added multi-column index '%s' -> '%s' with %zu fields\n",
// index_name.c_str(), generated_name.c_str(), field_indexes.size());
}
// Template implementation for AddColumnDefault
template<typename T>
void V9Builder::AddColumnDefault(const std::string& table_name,
const std::string& field_name,
const std::vector<uint8_t>& serialized_value) {
// Find the existing table
RawTableDefV9* table = findTableByName(table_name);
if (!table) {
fprintf(stderr, "ERROR: Table '%s' not found for default value on field '%s'\n",
table_name.c_str(), field_name.c_str());
return;
}
// Get field descriptors to find the field index
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()) {
fprintf(stderr, "ERROR: No field descriptors found for table %s\n", table_name.c_str());
return;
}
const auto& field_descs = it->second.fields;
uint16_t field_idx = 0;
bool field_found = false;
// Find the field indexView on GitHub (pinned to 524b4487d9)
Solutions
- Match the table name string in the default annotation exactly to the table macro's name
- Compile the table and its default annotation in the same translation unit to fix static-init ordering
- Check for duplicate table name registrations that overwrote the original
- After republishing, verify the column default shows in the table description
Example fix
// before ST_TABLE(player, ...); ST_COLUMN_DEFAULT(players, score, 0); // wrong table name // after ST_COLUMN_DEFAULT(player, score, 0);
Defensive patterns
Strategy: validation
Validate before calling
#include <spacetimedb/internal/v9_builder.h>
bool TableIsRegistered(const std::string& name) {
for (const auto& t : SpacetimeDB::Internal::GetV9Module().tables)
if (t.name == name) return true;
return false;
} Prevention
- Keep default-value annotations next to the table macro they target
- After table renames, sweep all annotations referencing the old name
- Confirm defaults in the published schema — their absence is silent
When it happens
Trigger: The default-value annotation's table_name string doesn't exactly match a registered table (typo/casing/renamed table), or the default registration static object initializes before the table's registration in another translation unit.
Common situations: Table renames during schema evolution; default annotations kept in a central file that initializes before the tables; copy-paste between similar table names; mixing macro generations so the table is registered under a different builder.
Related errors
- ERROR: Table '%s' not found when trying to add constraint to
- ERROR: Table '%s' not found for multi-column index '%s'
- ERROR: Skipping default-value registration '%s.%s' because c
- ERROR: Field %s.%s has primary_key constraint - cannot have
- ERROR: Field %s.%s has unique constraint - cannot have defau
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/c0f28a599166ba57.
Report an issue: GitHub.