clockworklabs/SpacetimeDB · error · Exception
Unrecognised extra bytes in the {description}
Error message
Unrecognised extra bytes in the {description} What it means
After decoding a BSATN-encoded payload into an anonymous view context, SpacetimeDB checks that the MemoryStream was fully consumed via EnsureNoUnreadBytes. Leftover bytes mean the encoded data contains more fields than the decoder knew how to read — usually a schema mismatch between writer and reader. The library throws because silently ignoring trailing bytes could hide data loss or corruption.
Source
Thrown at crates/bindings-csharp/Runtime/Internal/Module.cs:618
public static IViewContext CreateViewContext(
ulong sender_0,
ulong sender_1,
ulong sender_2,
ulong sender_3
)
{
var sender = Identity.From(MemoryMarshal.AsBytes([sender_0, sender_1, sender_2, sender_3]));
return newViewContext!(sender);
}
public static IAnonymousViewContext CreateAnonymousViewContext() => newAnonymousViewContext!();
public static void EnsureNoUnreadBytes(MemoryStream stream, string description)
{
if (stream.Position != stream.Length)
{
throw new Exception($"Unrecognised extra bytes in the {description}");
}
}
public static Errno WriteReducerError(BytesSink error, Exception e)
{
var error_str = e.Message ?? e.GetType().FullName ?? e.GetType().Name;
var error_bytes = System.Text.Encoding.UTF8.GetBytes(error_str);
error.Write(error_bytes);
return Errno.HOST_CALL_FAILURE;
}
private static void Write(this BytesSink sink, ReadOnlySpan<byte> bytes)
{
while (!bytes.IsEmpty)
{
var written = bytes.Length;
FFI.bytes_sink_write(sink, bytes, ref written);
bytes = bytes[written..];View on GitHub (pinned to 3653d2ed49)
Solutions
- Regenerate C# bindings and redeploy the module so writer and reader share the same schema version
- Verify you are decoding with the correct expected type for the payload
- Inspect the raw bytes: remove padding, truncation, or accidental concatenation of multiple payloads
- If the extra field is intentional on the writer side, add it to the reader type or use a forward-compatible decoding path
Example fix
// before var ctx = Module.CreateAnonymousViewContext(); ctx.Decode(oldBytes); // throws: Unrecognised extra bytes // after var ctx = Module.CreateAnonymousViewContext(); ctx.Decode(bytesProducedByCurrentSchema); // writer & reader schemas match
Defensive patterns
Strategy: try-catch
Validate before calling
// before decoding, sanity-check that the buffer is fully consumable by the expected type
var expected = Bsatn.SizeOf<MyPayloadType>(bytes);
if (bytes.Length != expected)
throw new InvalidOperationException(
$"Payload length {bytes.Length} != expected schema size {expected}"); Type guard
static bool IsFullyConsumable(MemoryStream s) => s.Position == s.Length;
Try / catch
try
{
var ctx = DecodeAnonymousViewContext(stream);
}
catch (Exception ex) when (ex.Message.StartsWith("Unrecognised extra bytes"))
{
logger.LogError(ex, "BSATN schema mismatch: reader consumed fewer bytes than payload contains");
throw new SchemaMismatchException(ex.Message, ex);
} Prevention
- Regenerate C# bindings whenever the server module schema changes
- Pin writer and reader to the same module version / schema hash
- Never hand-build or pad BSATN buffers; use the generated encoder
- Add a round-trip test: encode with the writer, decode with the reader, assert no leftover bytes
When it happens
Trigger: Calling a code path that ends in Module.EnsureNoUnreadBytes(stream, description) (e.g. anonymous view/context deserialization) with a buffer whose byte length exceeds what the expected type's BSATN decoder reads — decoding an older/newer struct version, wrong type, or corrupted/padded payload.
Common situations: Client and server module compiled from different schema versions (field added on the writer side); decoding bytes with the wrong expected type; manually concatenated or truncated BSATN buffers; stale generated bindings after a module update.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Tag {tag} is out of range of enum {typeof(T).Name}
- Invalid tag value, this state should be unreachable.
- Argument must be a I128
- Argument must be a I256
- Value {value} is out of range for enum {typeof(T).Name}
AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-09-06).
Data as JSON: /api/errors/de47748cbb25e673.
Report an issue: GitHub.