dotnet/wpf · error · InvalidOperationException

SR.Image_PropertyNotSupported

Error message

SR.Image_PropertyNotSupported

What it means

PropVariant.Init converts managed values into OLE PROPVARIANT representations. When a value of an unsupported managed type arrives in the branch that already handled known array/vector cases, it throws InvalidOperationException with Image_PropertyNotSupported: WPF metadata properties support only a fixed set of types.

Solutions

  1. Convert the value to a supported type before SetQuery: byte, short, int, long, float, double, string, bool, or arrays of those.
  2. For dates, store as string in the format the metadata field expects (EXIF date fields are strings).
  3. Check the metadata query documentation for the field's native type and marshal accordingly (e.g. (ushort) for EXIF SHORT fields).

Example fix

// before
metadata.SetQuery("/app1/ifd/exif:{ushort=36867}", DateTime.Now); // unsupported type

// after
metadata.SetQuery("/app1/ifd/exif:{ushort=36867}", DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss"));
Defensive patterns

Strategy: validation

Validate before calling

bool supported = v is byte || v is short || v is int || v is long || v is float || v is double || v is string || v is bool;
if (!supported) v = ConvertToSupported(v);

Type guard

static bool IsMetadataWritable(object v) => v is byte || v is short || v is int || v is long || v is float || v is double || v is string || v is bool;

Try / catch

try { metadata.SetQuery(q, value); } catch (InvalidOperationException ex) { /* coerce type and retry */ }

Prevention

When it happens

Trigger: BitmapMetadata.SetQuery (or SetPropertyValue paths) supplying a value whose runtime type falls through PropVariant.Init's supported-type switch after the vector/array branch — e.g. custom structs, DateTime arrays of odd element types, or boxed unsupported types.

Common situations: Writing arbitrary .NET objects into EXIF/XMP queries; reading metadata generically, modifying values, and writing them back with a changed type; passing decimal/nullable types that WPF does not map.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/4879139cdd23b8a0. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/PropVariant.cs:309

                else if (value is String[])
                {
                    Init (value as String[], false);
                }
                else if (value is bool[])
                {
                    bool[] boolArray =value as bool[];
                    short[] array = new short[boolArray.Length];

                    for (int i=0; i<boolArray.Length; i++)
                    {
                        array[i] = (short) (boolArray[i] ? -1 : 0);
                    }

                    InitVector(array, typeof(short), VarEnum.VT_BOOL);
                }
                else
                {
                    throw new System.InvalidOperationException(SR.Image_PropertyNotSupported);
                }
            }
            else
            {
                Type type = value.GetType();

                if (value is String)
                {
                    varType = (ushort) VarEnum.VT_LPWSTR;
                    pwszVal = Marshal.StringToCoTaskMemUni(value as String);
                }
                else if (type == typeof(sbyte))
                {
                    varType = (ushort) VarEnum.VT_I1;
                    cVal = (sbyte) value;
                }
                else if (type == typeof(byte))
                {

View on GitHub (pinned to 81131a70a4)