{"record":{"id":"0a955a50b4bb9599","repo":"clockworklabs/SpacetimeDB","slug":"argument-must-be-a-identity","errorCode":null,"errorMessage":"Argument must be a Identity","messagePattern":"Argument must be a Identity","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"crates/bindings-csharp/BSATN.Runtime/Builtins.cs","lineNumber":337,"sourceCode":"    }\n\n    // This must be explicitly implemented, otherwise record will generate a new implementation.\n    public override string ToString() => Util.ToHexBigEndian(value);\n\n    /// <inheritdoc cref=\"IComparable.CompareTo(object)\" />\n    public int CompareTo(object? value)\n    {\n        if (value is Identity other)\n        {\n            return CompareTo(other);\n        }\n        else if (value is null)\n        {\n            return 1;\n        }\n        else\n        {\n            throw new ArgumentException(\"Argument must be a Identity\", nameof(value));\n        }\n    }\n\n    /// <inheritdoc cref=\"IComparable{T}.CompareTo(T)\" />\n    public int CompareTo(Identity identity) => this.value.CompareTo(identity.value);\n}\n\n/// <summary>\n/// A timestamp that represents a unique moment in time (in the Earth's reference frame).\n///\n/// This type may be converted to/from a DateTimeOffset, but the conversion can lose precision.\n/// This type has less precision than DateTimeOffset (units of microseconds rather than units of 100ns).\n/// </summary>\n[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI\npublic record struct Timestamp(long MicrosecondsSinceUnixEpoch)\n    : IStructuralReadWrite,\n        IComparable<Timestamp>\n{","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-csharp/BSATN.Runtime/Builtins.cs#L319-L355","documentation":"The non-generic IComparable.CompareTo(object) on Identity throws ArgumentException for arguments that are neither an Identity nor null (null returns 1). Like the other SpacetimeDB ID structs, it deliberately rejects unrelated types rather than inventing an ordering.","triggerScenarios":"((IComparable)identity).CompareTo(boxed); non-generic sorts/searches over object[] or ArrayList mixing Identity with strings/Guids; reflection-based frameworks invoking CompareTo(object).","commonSituations":"Interop with non-generic or reflection-heavy libraries (serialization, grid sorting); shared comparison helpers typed as object.","solutions":["Use the typed overload identity.CompareTo(otherIdentity)","Keep Identity values in typed containers so generic comparison is used","Guard with a type test before object-based comparison","Use the hex string as the comparison key across heterogeneous systems"],"exampleFix":"// before\nobject key = GetSortKey();\nint c = ((IComparable)identity).CompareTo(key); // throws for non-Identity\n\n// after\nint c = key is Identity other ? identity.CompareTo(other) : throw new InvalidOperationException($\"Cannot compare Identity with {key?.GetType().Name}\");","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsIdentity(object? o) => o is Identity;","tryCatchPattern":null,"preventionTips":["Keep Identity values in strongly-typed containers","Use the typed CompareTo(Identity) overload","Narrow object inputs with pattern matching before comparing"],"tags":["csharp","identity","icomparable","type-mismatch","spacetimedb"],"backgroundTag":"invalid-argument-type","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}