Somewhere between this code and the abstractexpression.cpp code, you have changed the handling of the (m_valueType == null) case. It used to be handled by setting the key to null as in

        stringer.key(Members.VALUE_TYPE.name()).value(m_valueType == null ? null : m_valueType.name());

I don't know how this looks in the json but in the EE this got handled with 

    std::string valueTypeString = obj.valueForKey("VALUE_TYPE").asStr();
    value_type = stringToValue(valueTypeString);

This was followed by an assert that value_type was not == INVALID. So, whatever value comes out (at least with debug enabled) it not INVALID.

Your new code by-passes that assert and guarantees that the value_type remains as INVALID because there is now no such key in the json. I wonder of this case even still happens. If it does, it should have the same result in the EE as before, just to be safe.