clockworklabs/SpacetimeDB · error
NO_SUCH_VIEW
NO_SUCH_VIEW
Error message
ERROR: Invalid view ID %u (have %zu views)\n
What it means
Dispatch guard in Module::__call_view__: the host called a view by numeric ID >= g_view_handlers.size(). The function logs the message and returns -1 (NO_SUCH_VIEW), failing the view call. As with the reducer case, the server's view table from publish time disagrees with the handlers actually registered in the running binary.
Source
Thrown at crates/bindings-cpp/src/internal/Module.cpp:527
if (SpacetimeDB::Internal::has_reducer_error()) {
std::string error_msg = SpacetimeDB::Internal::get_reducer_error();
WriteBytes(error_sink, std::vector<uint8_t>(error_msg.begin(), error_msg.end()));
return StatusCode::HOST_CALL_FAILURE;
}
return StatusCode::OK;
}
// Dispatch function for views with ViewContext (has sender)
int16_t Module::__call_view__(
uint32_t id,
uint64_t sender_0, uint64_t sender_1, uint64_t sender_2, uint64_t sender_3,
BytesSource args_source,
BytesSink result_sink
) {
// Check if view ID is valid
if (id >= g_view_handlers.size()) {
fprintf(stderr, "ERROR: Invalid view ID %u (have %zu views)\n",
id, g_view_handlers.size());
return -1; // NO_SUCH_VIEW
}
// Create sender identity from the 4 uint64_t parts
std::array<uint8_t, 32> sender_bytes{};
std::memcpy(sender_bytes.data(), &sender_0, 8);
std::memcpy(sender_bytes.data() + 8, &sender_1, 8);
std::memcpy(sender_bytes.data() + 16, &sender_2, 8);
std::memcpy(sender_bytes.data() + 24, &sender_3, 8);
Identity sender_identity(sender_bytes);
// Create view context
ViewContext ctx(sender_identity);
// Get the handler
const auto& handler_info = g_view_handlers[id];View on GitHub (pinned to 6dee26c6ef)
Solutions
- Republish the module so the published view list matches the binary, then retry
- Keep view registration macros unconditional so the handler list is deterministic across builds
- Inspect server logs for module init errors that may have cut registration short
- Regenerate client bindings after any view schema change
Example fix
// before
#ifdef ENABLE_VIEWS
VIEW(list_items) { /* ... */ }
#endif
// after
VIEW(list_items) { /* ... */ } // registered in every build Defensive patterns
Strategy: validation
Validate before calling
// post-build test: assert view handler counts are stable // assert(Module::GetViewHandlerCount() == EXPECTED_VIEWS);
Prevention
- Register views unconditionally in every build configuration
- Republish after any view changes and regenerate bindings
- Watch for partial init failures in server logs that shrink the handler table
When it happens
Trigger: Stale module binary vs. server metadata (views added/removed without a clean republish); view registration macros conditionally compiled out; partial module init that skipped some __preinit__ view registrations.
Common situations: Adding or renaming views between module versions while old server-side metadata or cached bindings are in use; build-configuration differences stripping view macros.
Related errors
- NO_SUCH_REDUCER
- NO_SUCH_PROCEDURE
- ERROR: Invalid http handler ID %u (have %zu handlers)\n
- There is already a reducer, procedure, or view with the name
- View '${exportName}' can have at most one primaryKey() colum
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/96a7aa51cfecaf8e.
Report an issue: GitHub.