clockworklabs/SpacetimeDB · error · ArgumentException

Expected Identity hex string to be 64 characters long, but w

Error message

Expected Identity hex string to be 64 characters long, but was {hex.Length}.

What it means

Identity.FromHexString requires exactly 64 hex characters because an Identity wraps a 256-bit (32-byte) value. The length check runs before parsing, so any string of a different length fails immediately with ArgumentException instead of producing a malformed identity.

Source

Thrown at crates/bindings-csharp/BSATN.Runtime/Builtins.cs:290

    ///
    /// "0xb0b1b2..."
    /// ->
    /// [0xb0, 0xb1, 0xb2, ...]
    /// </summary>
    /// <param name="bytes"></param>
    public static Identity FromBigEndian(ReadOnlySpan<byte> bytes) =>
        Util.Read<Identity>(bytes, littleEndian: false);

    /// <summary>
    /// Create an Identity from a hex string.
    /// </summary>
    /// <param name="hex"></param>
    /// <returns></returns>
    public static Identity FromHexString(string hex)
    {
        if (hex.Length != 64)
        {
            throw new ArgumentException(
                $"Expected Identity hex string to be 64 characters long, but was {hex.Length}.",
                nameof(hex)
            );
        }

        return FromBigEndian(Util.StringToByteArray(hex));
    }

    // --- auto-generated ---
    public readonly struct BSATN : IReadWrite<Identity>
    {
        public Identity Read(BinaryReader reader) => new(new SpacetimeDB.BSATN.U256().Read(reader));

        public void Write(BinaryWriter writer, Identity value) =>
            new SpacetimeDB.BSATN.U256().Write(writer, value.value);

        // --- / auto-generated ---

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Pass exactly 64 hex characters (32 bytes) with no prefix or separators
  2. Verify the ID kind first - Identity is 64 chars, ConnectionId is 32 chars - and pick the matching FromHexString
  3. Normalize (strip 0x/dashes/whitespace) before calling and assert length == 64
  4. Generate canonical strings via Identity.ToHexString() for storage and round-tripping

Example fix

// before
var identity = Identity.FromHexString(userInput); // "0x" + 64 chars -> 66, throws

// after
var hex = userInput.Trim();
if (hex.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) hex = hex[2..];
var identity = Identity.FromHexString(hex);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidIdentityHex(string hex) =>
    hex.Length == 64 && hex.All(c => c is (>= '0' and <= '9') or (>= 'a' and <= 'f') or (>= 'A' and <= 'F'));

if (IsValidIdentityHex(hex)) { var id = Identity.FromHexString(hex); }

Prevention

When it happens

Trigger: Passing a ConnectionId hex string (32 chars) or an Ethereum-style address (40 chars); a string with 0x prefix (66 chars); dash/brace-formatted strings; truncated or whitespace-padded input.

Common situations: Confusing which ID a UI/config field expects (Identity vs ConnectionId vs Address); pasting values from wallet-style tooling that includes 0x; string manipulation that trims or adds characters.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/e4b1862a941dc844. Report an issue: GitHub.