clockworklabs/SpacetimeDB · error
ERROR: Failed to read from BytesSource: %d\n
Error message
ERROR: Failed to read from BytesSource: %d\n
What it means
Runtime FFI error inside ConsumeBytes' unknown-length read loop: FFI::bytes_source_read returned a status other than 0 (OK) or -1 (EXHAUSTED) while draining the BytesSource that carries reducer/HTTP arguments across the Wasm boundary. The message is logged and the loop breaks, so the caller receives a truncated buffer and the failure usually resurfaces as a BSATN deserialization error downstream.
Source
Thrown at crates/bindings-cpp/src/internal/Module.cpp:417
auto ret = FFI::bytes_source_remaining_length(source, &remaining_len);
if (ret != 0) {
// If we can't get the length, fall back to incremental reading
// This shouldn't happen with current host implementation
constexpr size_t CHUNK_SIZE = 1024;
iter_buf.reserve(CHUNK_SIZE);
while (true) {
size_t chunk_size = CHUNK_SIZE;
size_t old_size = iter_buf.size();
iter_buf.resize(old_size + chunk_size);
ret = FFI::bytes_source_read(source, iter_buf.data() + old_size, &chunk_size);
iter_buf.resize(old_size + chunk_size); // Resize to actual bytes read
if (ret == -1) { // EXHAUSTED
break;
} else if (ret != 0) { // Error
fprintf(stderr, "ERROR: Failed to read from BytesSource: %d\n", ret);
break;
}
}
return iter_buf.release();
}
// Reserve exact size needed (often no-op since pool buffer is 64 KiB)
iter_buf.resize(remaining_len); // Resize to exact size BEFORE reading
// Read all bytes - should complete in one call since we have capacity
size_t bytes_read = 0;
while (bytes_read < remaining_len) {
size_t chunk_size = remaining_len - bytes_read;
ret = FFI::bytes_source_read(source, iter_buf.data() + bytes_read, &chunk_size);
bytes_read += chunk_size;
if (ret == -1) { // EXHAUSTED
break;View on GitHub (pinned to 6dee26c6ef)
Solutions
- Rebuild and republish the module with the same spacetimedb toolchain/CLI version used by the server so the FFI ABI matches
- Check the server/host logs for the underlying read failure at the same timestamp - the module-side message only mirrors it
- If it reproduces with a specific large argument, reduce the payload or split the call to rule out size-related truncation
- If persistent, report with the returned status code (the %d value) to SpacetimeDB maintainers - nonzero non-minus-one statuses are host-side faults
Defensive patterns
Strategy: fallback
Prevention
- Build and publish the module with the same spacetimedb CLI version as the server
- Treat this as an infrastructure fault: check host/server logs at the same timestamp
- Make reducers tolerant of argument deserialization failure (validate inputs, return clean errors) so a truncated stream surfaces as a user-visible error, not a crash
When it happens
Trigger: The host-side byte stream faults mid-read while the module drains reducer arguments of unknown length; ABI/host version mismatch between the module binary and the spacetimedb host; corrupted or closed BytesSource passed across the FFI boundary.
Common situations: Publishing a module built with an older bindings-cpp ABI against a newer server (or vice versa); intermittent host I/O failures; truncation of large argument payloads at the Wasm boundary.
Related errors
- unable to decode args
- cannot deserialize refs without a typespace
- Invalid JSON: failed to parse string
- wrong number of elements
- too many elements
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/8d84f59781c32441.
Report an issue: GitHub.