System.InvalidProgramException: Common Language Runtime detected an invalid program

I just spent a while fighting an exception that was being thrown from within a .NET runtime-generated assembly—specifically from Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter{MyClassName}.Write7_{MyClassName}. There were plenty of search results that didn’t apply to my problem, but I didn’t find any that directly addressed the issue I was encountering, so I wanted to write up a quick post to possibly save someone some time in the future.

tl;dr

The object being serialized included this method:

public static bool ShouldSerializeFoobarProp() => false;

Eliminating the static declaration made the problem go away[1].

The full story

I’ve got a class defined which can be populated from and/or serialized to XML. It uses a bunch of [XmlElement("foobar")] annotations, and is 95% just used as a data structure. It gets serialized to XML thusly:

XmlSerializer s = new XmlSerializer(typeof(MyFoobarClass));

using (StringWriter w = new StringWriter())
{
	XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
	xmlnsEmpty.Add("", "");

	try
	{
		s.Serialize(w, myFoobarObject, xmlnsEmpty);

However, there are a few public properties of the class that, while useful elsewhere in the code, don’t necessarily make sense when serializing to XML. I employed the ShouldSerialize{PropertyName} pattern[2] to selectively serialize certain elements and attributes only when useful, and never serialize another property.[1]

That all worked fine. At some point, I worked through a bunch of code analysis hints, one of which correctly pointed out that CA1822 Member ShouldSerialize{Foobar} does not access instance data and can be marked as static (Shared in VisualBasic). I didn’t have a unit test for this (tsk, tsk!), so everything looked fine. This serialization doesn’t even run during most normal use of the software, so no red flags were raised for quite a while. Thankfully, before these changes shipped, I did exercise this code path, and was greeted with System.InvalidProgramException: Common Language Runtime detected an invalid program thrown from the call to s.Serialize(...).

Search results for this exception pointed me to corrupt builds, x86/x64 mismatch, corrupt Visual Studio session data, corrupt .NET runtime installations, etc, none of which was helpful in this case. Eventually I found a StackOverflow answer from Youssef Moussaoui that talked about XmlSerializer changes in .NET 4.5.

I tried changing the .NET targeted runtime for my projects to no avail, but he also included an app.config toggle to force legacy behavior. When I tried that, I got a new exception! This one actually occurred earlier in the execution—when attempting to construct the serializer—but more importantly made a reference to my ShouldSerizlier{Foobar} static method:

System.InvalidOperationException: ‘Unable to generate a temporary class (result=1).
error CS0176: Member ‘MyFoobarClass.ShouldSerializeFoobarProp()’ cannot be accessed with an instance reference; qualify it with a type name instead’

That was enough to point me to that method, which I saw was marked static. After eliminating the static keyword (and then silencing the resulting code analysis hint), voilĂ , everything was happy once again!

[1] This, of course, turns out to not be the right way to universally ignore an element for serialization. The [XmlIgnore] annotation/attribute is the much more obvious and easy way to accomplish this.

[2] I’m sure I learned about the ShouldSerialize{PropertyName} functionality on StackOverflow, specific to XmlSerializer, but I wasn’t able to easily find official documentation of the feature in that context when writing this post. This reference to winforms was the best I could do.

Tags: , , ,

Leave a Reply