{"record":{"id":"e02b25b4cedef0de","repo":"dotnet/wpf","slug":"property-data-must-be-a-non-reference-variant-compatible-e02b25","errorCode":null,"errorMessage":"Property data must be a non-reference variant compatible type.","messagePattern":"Property data must be a non-reference variant compatible type\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/SerializationHelper.cs","lineNumber":322,"sourceCode":"                return (VarEnum.VT_ARRAY | VarEnum.VT_BOOL);\n            }\n            else if (typeof(String) == type)\n            {\n                return VarEnum.VT_BSTR;\n            }\n            else if (typeof(Decimal) == type)\n            {\n                return VarEnum.VT_DECIMAL;\n            }\n            else if (typeof(Decimal[]) == type)\n            {\n                return (VarEnum.VT_ARRAY | VarEnum.VT_DECIMAL);\n            }\n            else\n            {\n                if (throwOnError)\n                {\n                    throw new ArgumentException(SR.InvalidDataTypeForExtendedProperty);\n                }\n                else\n                {\n                    return VarEnum.VT_UNKNOWN;\n                }\n            }\n        }\n    }\n}\n","sourceCodeStart":304,"sourceCodeEnd":332,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/SerializationHelper.cs#L304-L332","documentation":"Thrown by SerializationHelper.ConvertToVarEnum (with throwOnError=true) when an ExtendedProperty value's type has no compatible non-reference VARIANT representation. ISF extended properties must be storable as a by-value VarEnum; types like objects, unknown COM references, or unsupported managed types cannot be serialized into ISF.","triggerScenarios":"Adding a Stroke/StrokeCollection/StylusPoint Description extended property whose value is not a primitive (e.g. a custom class, array of unsupported element type, or object) and then serializing to ISF via StrokeCollectionSerializer.Save / ExtendedPropertySerializer.EncodeAsISF.","commonSituations":"Developers storing arbitrary .NET objects in Stroke extended properties and later saving to ISF; passing byte[][] or nested collections; upgrading code that previously used XML persistence to ISF persistence.","solutions":["Store only VARIANT-compatible types in extended properties: numeric primitives, bool, string, DateTime, byte[], and safe arrays of these","Convert custom objects to a byte[] or string representation before adding as an extended property","Catch ArgumentException around save/serialization and remove or convert offending ExtendedProperty keys","If the value type is legitimately unsupported (ConvertToVarEnum returned VT_UNKNOWN when throwOnError=false), skip persisting that property"],"exampleFix":"// before\nstroke.AddPropertyData(myGuid, new MyCustomClass { X = 1 }); // throws on ISF save\n// after\nstroke.AddPropertyData(myGuid, BitConverter.GetBytes(myValue)); // store as byte[]\n// or serialize the object to a string/byte[] yourself:\nstroke.AddPropertyData(myGuid, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj)));","handlingStrategy":"type-guard","validationCode":"static readonly HashSet<Type> VariantCompatible = new() {\n    typeof(int), typeof(uint), typeof(short), typeof(ushort), typeof(long), typeof(ulong),\n    typeof(float), typeof(double), typeof(decimal), typeof(bool), typeof(string),\n    typeof(DateTime), typeof(byte[])\n};\nstatic bool IsExtendedPropertyStorable(object v) =>\n    v != null && (VariantCompatible.Contains(v.GetType()) ||\n      (v is Array a && a.Length > 0 && VariantCompatible.Contains(a.GetType().GetElementType())));","typeGuard":"bool IsStorableExtendedProperty(object value) => value is int or uint or short or ushort or long or ulong or float or double or decimal or bool or string or DateTime or byte[];","tryCatchPattern":"try { scs.Save(stream); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"variant\")) {\n    log.Warn(\"Unsupported extended property type\", ex);\n    // remove offending ExtendedProperty and retry save\n}","preventionTips":["Only add primitive/string/byte[] values via AddPropertyData","Serialize custom objects to byte[] or string yourself before storing","Test round-trip (save+load) of strokes with extended properties in CI"],"tags":["ink","isf","extended-properties","serialization","type-mismatch"],"backgroundTag":"unsupported-dtype","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}