JamesNK/Newtonsoft.Json · error · ArgumentException
Can not convert {0} to String.
Error message
Can not convert {0} to String. What it means
Thrown by the explicit cast operator 'operator string?(JToken?)' when the token cannot be resolved to a scalar JValue. StringTypes is the broadest set ({Date, Integer, Float, String, Comment, Raw, Boolean, Bytes, Guid, TimeSpan, Uri}) and the overload is nullable (so JSON null returns null). Therefore this throw is ONLY reached when the token is not a JValue at all — i.e. a JObject, JArray, or JConstructor (EnsureValue returns null).
Source
Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:1309
return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
}
/// <summary>
/// Performs an explicit conversion from <see cref="JToken"/> to <see cref="String"/>.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator string?(JToken? value)
{
if (value == null)
{
return null;
}
JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, StringTypes, true))
{
throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
}
if (v.Value == null)
{
return null;
}
if (v.Value is byte[] bytes)
{
return Convert.ToBase64String(bytes);
}
#if HAVE_BIG_INTEGER
if (v.Value is BigInteger integer)
{
return integer.ToString(CultureInfo.InvariantCulture);
}
#endifView on GitHub (pinned to 4f73e74372)
Solutions
- Check token["name"] is a JValue (or token["name"]?.Type != JTokenType.Object/Array) before the string cast.
- If the field is an object, navigate to the nested string scalar (e.g. payload["name"]["full"]).
- Use token["name"]?.ToString() or token.Value<string>("name") which return null instead of throwing for object/array nodes.
- Re-examine the indexing path; this error almost always means you are one level too shallow or too deep.
Example fix
// before string name = (string)payload["name"]; // throws when name is an object // after string name = (payload["name"] is JValue) ? (string)payload["name"]! : null;
Defensive patterns
Strategy: type-guard
Validate before calling
string? name = (payload["name"] is JValue) ? (string)payload["name"]! : null;
Type guard
static bool IsScalar(JToken? t) => t is JValue;
Try / catch
string? name;
try { name = (string)payload["name"]; }
catch (ArgumentException) { name = null; } Prevention
- This throw means the node is an object/array, not a scalar — re-check your indexing depth.
- Use token["name"]?.ToString() or Value<string>("name") to avoid the throw.
- If the field is an object, navigate to the nested scalar before casting.
When it happens
Trigger: Calling (string)token["name"] where the node is a JSON object {...} or array [...] instead of a scalar, or the node is a JConstructor. Scalars of every kind (numbers, dates, GUIDs, null) convert fine and do not throw here.
Common situations: Indexing payload["name"] and accidentally grabbing a child object (e.g. { "first": ..., "last": ... }); array-valued field where a string was expected; schema change that nested the scalar inside an object.
Related errors
- Can not convert {0} to Single.
- Can not convert {0} to UInt32.
- Can not convert {0} to UInt64.
- Can not convert {0} to byte array.
- Can not convert {0} to Guid.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/7a24ca3db03ca9e7.
Report an issue: GitHub.