clockworklabs/SpacetimeDB · error · ArgumentException
Byte array must be exactly
Error message
Byte array must be exactly {Size} bytes long. What it means
U128.FromBytesBigEndian constructs a 128-bit unsigned integer from exactly 16 big-endian bytes (U128.Size). Any other length throws ArgumentException because a buffer of the wrong size cannot unambiguously populate the upper and lower 64-bit halves.
Solutions
- Check bytes.Length == 16 (U128.Size) and slice the source to exactly 16 bytes before calling
- Fix the upstream producer (e.g. hex string must decode to 16 bytes)
- If the value is 32 bytes, use U256.FromBytesBigEndian instead
Example fix
// before var u = U128.FromBytesBigEndian(hash[..8]); // ArgumentException: Byte array must be exactly 16 bytes long. // after var u = U128.FromBytesBigEndian(hash[..16]); // exactly 16 bytes
Defensive patterns
Strategy: validation
Validate before calling
static bool IsU128Bytes(ReadOnlySpan<byte> bytes) => bytes.Length == U128.Size; // 16
Try / catch
try
{
value = U128.FromBytesBigEndian(source);
}
catch (ArgumentException ex)
{
throw new FormatException($"Expected 16 bytes for U128, got {source.Length}", ex);
} Prevention
- Centralize width constants (16 for U128, 32 for U256) instead of magic numbers
- Prefer FromHexString-style entry points that validate length up front
- Double-check slice bounds when carving buffers for id conversion
When it happens
Trigger: Passing a span/array whose length is not exactly 16: hex-decoding a shortened string, slicing with the wrong range (bytes[..8]), or feeding variable-length hash/digest output.
Common situations: Converting GUIDs or digests into U128-backed types (Uuid, Identity) with wrong slicing; interop code assuming different fixed widths; off-by-one parsing loops.
Related errors
- Argument must be a U128
- Error while reading : expected source span to be bytes…
- Argument must be a I128
- Argument must be a I256
- Argument must be a U256
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/ffcbb70eb3824a3e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-csharp/BSATN.Runtime/BSATN/U128.cs:42
/// <summary>Initializes a new instance of the <see cref="U128" /> struct.</summary>
/// <param name="upper">The upper 64-bits of the 128-bit value.</param>
/// <param name="lower">The lower 64-bits of the 128-bit value.</param>
public U128(ulong upper, ulong lower)
{
_upper = upper;
_lower = lower;
}
internal ulong Lower => _lower;
internal ulong Upper => _upper;
/// Returns a <see cref="U128" /> from a big-endian byte array.
public static U128 FromBytesBigEndian(ReadOnlySpan<byte> bytes)
{
if (bytes.Length != Size)
{
throw new ArgumentException(
$"Byte array must be exactly {Size} bytes long.",
nameof(bytes)
);
}
var upper = BinaryPrimitives.ReadUInt64BigEndian(bytes[..8]);
var lower = BinaryPrimitives.ReadUInt64BigEndian(bytes[8..16]);
return new U128(upper, lower);
}
public byte[] ToBytesBigEndian()
{
var bytes = new byte[Size];
BinaryPrimitives.WriteUInt64BigEndian(bytes.AsSpan(0, 8), _upper);
BinaryPrimitives.WriteUInt64BigEndian(bytes.AsSpan(8, 8), _lower);
View on GitHub (pinned to 6dee26c6ef)