JamesNK/Newtonsoft.Json · error · JsonException
New item to be added to collection must be compatible with {
Error message
New item to be added to collection must be compatible with {0}. What it means
Thrown by IBindingList.AddNew on a JContainer when the AddingNew handler did supply an object but it is not a JToken. AddNew validates that the user-provided NewObject is assignable to JToken; otherwise it throws JsonException because a JContainer can only hold JToken children.
Source
Thrown at Src/Newtonsoft.Json/Linq/JContainer.cs:1137
#region IBindingList Members
#if HAVE_COMPONENT_MODEL
void IBindingList.AddIndex(PropertyDescriptor property)
{
}
object IBindingList.AddNew()
{
AddingNewEventArgs args = new AddingNewEventArgs();
OnAddingNew(args);
if (args.NewObject == null)
{
throw new JsonException("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType()));
}
if (!(args.NewObject is JToken newItem))
{
throw new JsonException("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JToken)));
}
Add(newItem);
return newItem;
}
bool IBindingList.AllowEdit => true;
bool IBindingList.AllowNew => true;
bool IBindingList.AllowRemove => true;
void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
{
throw new NotSupportedException();
}
View on GitHub (pinned to 4f73e74372)
Solutions
- In the AddingNew handler, wrap or build a JToken: e.NewObject = JToken.FromObject(myPoco) or new JObject(new JProperty("x", val)).
- Return a fresh empty JObject/JArray/JValue matching the container's expected child type.
- Avoid AddNew; construct the JToken yourself and call Add.
Example fix
// before jArray.AddingNew += (s, e) => e.NewObject = new MyItem(); // not a JToken // after jArray.AddingNew += (s, e) => e.NewObject = JToken.FromObject(new MyItem());
Defensive patterns
Strategy: type-guard
Validate before calling
static JToken ToJToken(object o) => o switch
{
JToken t => t,
_ => JToken.FromObject(o)
};
jArray.AddingNew += (s, e) => e.NewObject = ToJToken(CreateNewItem()); Type guard
static bool IsJTokenCompatible(object? o) => o is JToken;
Try / catch
try { ((IBindingList)container).AddNew(); }
catch (JsonException ex) when (ex.Message.Contains("must be compatible with"))
{
// Handler returned a non-JToken; wrap and add manually.
container.Add(JToken.FromObject(CreateNewItem()));
} Prevention
- In AddingNew handlers, always return a JToken (use JToken.FromObject for POCOs).
- Unit-test the handler by triggering AddNew.
- Avoid returning domain model types from AddingNew on a JContainer.
When it happens
Trigger: Subscribing to AddingNew and setting e.NewObject to a POCO, string, int, DataRow, or any non-JToken type, then triggering AddNew (directly or via BindingSource.AddNew).
Common situations: Handlers that return a domain model instead of a JSON node; copy-paste of an AddingNew handler from a non-JToken list; mixing typed model objects into a JObject/JArray binding surface.
Related errors
- Could not determine new value to add to '{0}'.
- Newtonsoft.Json support for System.ComponentModel is not com
- Argument is not a JToken.
- Can not add {0} to {1}.
- Accessed JObject values with invalid key value: {0}. Object
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/c170c4a0b7d0e80a.
Report an issue: GitHub.