clockworklabs/SpacetimeDB · error · ArgumentException
Argument must be a I128
Error message
Argument must be a I128
What it means
I128 is the SpacetimeDB BSATN.Runtime 128-bit signed integer type. It implements IComparable, and the untyped CompareTo(object?) overload only accepts another I128 (or null, which sorts after). Passing any other type throws ArgumentException because an I128 cannot be meaningfully ordered against an unrelated value.
Solutions
- Use the typed CompareTo(I128) overload or the <, >, == operators instead of the object-based overload
- Pattern-match and convert before comparing: if (other is I128 i) ... else convert explicitly
- When sorting mixed data, homogenize the array to I128[] first or supply a custom IComparer<object>
Example fix
// before
I128 a = GetAmount();
object other = 42L;
int cmp = a.CompareTo(other); // ArgumentException: Argument must be a I128
// after
if (other is I128 other128)
{
int cmp = a.CompareTo(other128);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Only invoke the untyped CompareTo when the boxed value is compatible static bool CanCompareWithI128(object? other) => other is null || other is SpacetimeDB.I128;
Type guard
static bool IsI128(object? value) => value is SpacetimeDB.I128;
Try / catch
try
{
var cmp = ((IComparable)i128Value).CompareTo(boxed);
}
catch (ArgumentException)
{
// heterogeneous comparison: convert the operand to I128 or sort by type name instead
} Prevention
- Prefer the typed CompareTo(I128) overload or the <, >, == operators
- Keep collections homogeneous (I128[] rather than object[]) before sorting
- Pattern-match boxed values (if (o is I128 x)) before comparing
- Avoid object/dynamic round-trips for 128-bit ids
When it happens
Trigger: Invoking ((IComparable)i128).CompareTo(obj) where the boxed argument is a long, decimal, I256, string, or any non-I128 type. Typical entry points: Array.Sort on an object[], ArrayList ordering, or comparing values deserialized as object.
Common situations: Sorting or searching heterogeneous collections; porting code that compared BigInteger or decimal against 128-bit ids; dynamic/object round-trips through JSON or old collection APIs.
Related errors
- Argument must be a I256
- Argument must be a U128
- Argument must be a U256
- Argument must be a ConnectionId
- Argument must be a Identity
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/1b63ead3ea6bb60d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-csharp/BSATN.Runtime/BSATN/I128.cs:49
internal ulong Lower => _lower;
internal ulong Upper => _upper;
/// <inheritdoc cref="IComparable.CompareTo(object)" />
public int CompareTo(object? value)
{
if (value is I128 other)
{
return CompareTo(other);
}
else if (value is null)
{
return 1;
}
else
{
throw new ArgumentException("Argument must be a I128", nameof(value));
}
}
/// <inheritdoc cref="IComparable{T}.CompareTo(T)" />
public int CompareTo(I128 value)
{
if (this < value)
{
return -1;
}
else if (this > value)
{
return 1;
}
else
{
return 0;
}View on GitHub (pinned to 6dee26c6ef)