JamesNK/Newtonsoft.Json · error · ArgumentException
Object must be of type Uri.
Error message
Object must be of type Uri.
What it means
Thrown by JValue.CompareTo when the token's JSON type is JTokenType.Uri and the operand is not a Uri. Uri JValues compare their underlying string forms with Comparer<string>; an operand that cannot be treated as a Uri is rejected. Note the operand is tested with `as Uri` so derived Uri types are accepted but strings are not.
Source
Thrown at Src/Newtonsoft.Json/Linq/JValue.cs:385
byte[]? bytesA = objA as byte[];
MiscellaneousUtils.Assert(bytesA != null);
return MiscellaneousUtils.ByteArrayCompare(bytesA!, bytesB);
case JTokenType.Guid:
if (!(objB is Guid))
{
throw new ArgumentException("Object must be of type Guid.");
}
Guid guid1 = (Guid)objA;
Guid guid2 = (Guid)objB;
return guid1.CompareTo(guid2);
case JTokenType.Uri:
Uri? uri2 = objB as Uri;
if (uri2 == null)
{
throw new ArgumentException("Object must be of type Uri.");
}
Uri uri1 = (Uri)objA;
return Comparer<string>.Default.Compare(uri1.ToString(), uri2.ToString());
case JTokenType.TimeSpan:
if (!(objB is TimeSpan))
{
throw new ArgumentException("Object must be of type TimeSpan.");
}
TimeSpan ts1 = (TimeSpan)objA;
TimeSpan ts2 = (TimeSpan)objB;
return ts1.CompareTo(ts2);
default:
throw MiscellaneousUtils.CreateArgumentOutOfRangeException(nameof(valueType), valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType));
}View on GitHub (pinned to 4f73e74372)
Solutions
- Wrap the operand in a Uri: token.CompareTo(new Uri(text)).
- Compare the string forms directly: ((Uri)token.Value<Uri>()).ToString() == text.
- Standardize on a single representation (Uri or string) for URI-typed fields.
Example fix
// before
int c = uriToken.CompareTo("https://example.com");
// after
int c = uriToken.CompareTo(new Uri("https://example.com")); Defensive patterns
Strategy: type-guard
Validate before calling
if (other is Uri u) { int c = uriToken.CompareTo(u); } else if (other is string s) { int c = uriToken.CompareTo(new Uri(s)); } Type guard
static bool IsUri(object? o) => o is Uri;
Try / catch
try { int c = token.CompareTo(other); } catch (ArgumentException ex) when (ex.Message.Contains("Uri")) { /* wrap in Uri */ } Prevention
- Wrap string operands in new Uri(...) before comparing Uri JValues.
- Standardize on Uri for URI-typed fields.
- Type-check operands before CompareTo.
When it happens
Trigger: Comparing a Uri JValue (created from new JValue(new Uri("https://x"))) against a string literal such as token.CompareTo("https://x"), or against any non-Uri object. Happens during sorting or equality on token collections.
Common situations: Storing URL fields as Uri-typed JValues and then comparing against string constants in LINQ-to-JSON code; mixing Uri and string representations of the same URL.
Related errors
- Object must be of type byte[].
- Object must be of type Guid.
- Object must be of type TimeSpan.
- Could not determine JSON object type for type {0}.
- Cannot access child value on {0}.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/e0199dbfc0b6be6e.
Report an issue: GitHub.