clockworklabs/SpacetimeDB · error · anyhow::Error
`create_bytes_source`: `Bytes` has length {}, which is great
Error message
`create_bytes_source`: `Bytes` has length {}, which is greater than `u32::MAX` {} What it means
WasmInstanceEnv::create_bytes_source stores a host-side bytes::Bytes buffer for the wasm32 guest to consume via syscalls. The bytes_source_remaining_length syscall reports the length as a u32, so buffers larger than u32::MAX (about 4 GiB) cannot be represented; additionally the guest cannot hold such a buffer in WASM32 memory. The host therefore rejects oversized buffers up front instead of overflowing.
Source
Thrown at crates/core/src/host/wasmtime/wasm_instance_env.rs:262
.expect("allocating next `BytesSink` overflowed `u32`");
id
}
/// Binds `bytes` to the environment and assigns it an ID.
///
/// If `bytes` is empty, `BytesSourceId::INVALID` is returned.
fn create_bytes_source(&mut self, bytes: bytes::Bytes) -> RtResult<BytesSourceId> {
// Pass an invalid source when the bytes were empty.
// This allows the module to avoid allocating and make a system call in those cases.
if bytes.is_empty() {
Ok(BytesSourceId::INVALID)
} else if bytes.len() > u32::MAX as usize {
// There's no inherent reason we need to error here,
// other than that it makes it impossible to report the length in `bytes_source_remaining_length`
// and that all of our usage of `BytesSource`s as of writing (pgoldman 2025-09-26)
// are to immediately slurp the whole thing into a buffer in guest memory,
// which can't hold buffers this big because it's WASM32.
Err(anyhow::anyhow!(
"`create_bytes_source`: `Bytes` has length {}, which is greater than `u32::MAX` {}",
bytes.len(),
u32::MAX,
))
} else {
let id = self.alloc_bytes_source_id()?;
self.bytes_sources.insert(id, BytesSource { bytes });
Ok(id)
}
}
pub fn create_extra_bytes_source(&mut self, bytes: bytes::Bytes) -> RtResult<BytesSourceId> {
self.create_bytes_source(bytes)
}
fn free_bytes_source(&mut self, id: BytesSourceId) {
if self.bytes_sources.remove(&id).is_none() {
log::warn!("`free_bytes_source` on non-existent source {id:?}");View on GitHub (pinned to 6dee26c6ef)
Solutions
- Enforce a maximum payload size at the API boundary and reject oversize inputs with a clear message before they reach the host bridge
- Split the payload into chunks below the limit and reassemble in the module or across multiple calls
- Store very large blobs out-of-band and pass a reference instead of raw bytes
Example fix
// before
let id = env.create_bytes_source(bytes)?; // bytes.len() > u32::MAX -> error
// after
const MAX_BYTES: usize = u32::MAX as usize;
if bytes.len() > MAX_BYTES {
return Err(anyhow::anyhow!(
"payload of {} bytes exceeds the 4 GiB wasm bridge limit; chunk the upload",
bytes.len(),
));
}
let id = env.create_bytes_source(bytes)?; Defensive patterns
Strategy: validation
Validate before calling
// Validate payload size before crossing the wasm bridge
const MAX_BYTES_SOURCE: usize = u32::MAX as usize;
fn check_bytes_source_size(len: usize) -> Result<(), anyhow::Error> {
if len > MAX_BYTES_SOURCE {
Err(anyhow::anyhow!("payload of {len} bytes exceeds the 4 GiB wasm bridge limit"))
} else {
Ok(())
}
} Type guard
fn fits_bytes_source(bytes: &bytes::Bytes) -> bool {
!bytes.is_empty() && bytes.len() <= u32::MAX as usize
} Try / catch
match env.create_bytes_source(bytes) {
Err(e) if e.to_string().contains("greater than `u32::MAX`") => {
// Reject or chunk the upload at the API boundary
}
other => other,
} Prevention
- Cap request/reducer payload sizes well below 4 GiB at the edge
- Chunk large uploads and reassemble in the module
- Add fuzz/soak tests with oversize buffers to confirm clean rejection
When it happens
Trigger: Passing a reducer argument, message, or blob larger than 4 GiB minus 1 into a host call that creates a bytes source (e.g. via create_extra_bytes_source on the instance env).
Common situations: Bulk-loading very large binary payloads in a single call; unbounded user-supplied input sizes; tests with synthetic huge buffers.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- {CALL_PROCEDURE_DUNDER} export is not a function
- {CALL_PROCEDURE_DUNDER} export is a function with incorrect
- {CALL_VIEW_DUNDER} export is not a function
- {CALL_VIEW_DUNDER} export is a function with incorrect type:
- {CALL_VIEW_ANON_DUNDER} export is not a function
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/44f3842406b553b3.
Report an issue: GitHub.