JamesNK/Newtonsoft.Json · error · ArgumentException

Value must be an XML object.

Error message

Value must be an XML object.

What it means

Thrown by XmlNodeConverter.WrapXml when the value passed for serialization is neither an XObject (System.Xml.Linq) nor an XmlNode (System.Xml). The converter can only transform XML DOM objects to/from JSON; any other runtime type triggers this ArgumentException.

Source

Thrown at Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs:1030

            }
        }

        private IXmlNode WrapXml(object value)
        {
#if HAVE_XLINQ
            if (value is XObject xObject)
            {
                return XContainerWrapper.WrapNode(xObject);
            }
#endif
#if HAVE_XML_DOCUMENT
            if (value is XmlNode node)
            {
                return XmlNodeWrapper.WrapNode(node);
            }
#endif

            throw new ArgumentException("Value must be an XML object.", nameof(value));
        }

        private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager)
        {
            List<IXmlNode>? parentElements = null;

            IXmlNode? parent = node;
            while ((parent = parent.ParentNode) != null)
            {
                if (parent.NodeType == XmlNodeType.Element)
                {
                    if (parentElements == null)
                    {
                        parentElements = new List<IXmlNode>();
                    }

                    parentElements.Add(parent);
                }

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Pass only XmlDocument, XmlElement, XDocument, or XElement values to XmlNodeConverter.
  2. Remove the XmlNodeConverter attribute from non-XML properties.
  3. If you need JSON<->object conversion (not JSON<->XML), use the default serializer or a different converter.

Example fix

// before: converter applied to a non-XML object
[JsonConverter(typeof(XmlNodeConverter))]
public MyPoco Config { get; set; }

// after: serialize XML document directly
var doc = new XmlDocument(); doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
Defensive patterns

Strategy: type-guard

Validate before calling

object value = GetValue();
if (value != null && !(value is System.Xml.XmlNode) && !(value is System.Xml.Linq.XObject))
    throw new InvalidOperationException($"XmlNodeConverter requires an XML object, got {value.GetType()}");

Type guard

static bool IsXmlObject(object v) =>
    v is System.Xml.XmlNode || v is System.Xml.Linq.XObject;

Try / catch

try { conv.WriteJson(writer, value, serializer); }
catch (ArgumentException ex) when (ex.Message.Contains("must be an XML object"))
{
    throw new InvalidOperationException($"XmlNodeConverter got {value?.GetType()}", ex);
}

Prevention

When it happens

Trigger: Serializing a non-XML object through XmlNodeConverter, e.g. applying [JsonConverter(typeof(XmlNodeConverter))] to a POCO, a string, or an XElement-wrapping custom type that does not inherit from XObject/XmlNode.

Common situations: Misapplying XmlNodeConverter to a business object instead of an XmlDocument/XDocument. A refactor changed the property type away from XML while the converter attribute remained. Polymorphic values where the actual instance is a plain object.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/14b30a331b249217. Report an issue: GitHub.