{"record":{"id":"6c1899c9bed42fab","repo":"dotnet/wpf","slug":"only-string-and-datetime-types-are-supported-for-marshalling","errorCode":null,"errorMessage":"Only string and DateTime types are supported for marshalling to PROPVARIANT.","messagePattern":"Only string and DateTime types are supported for marshalling to PROPVARIANT\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/indexingfiltermarshaler.cs","lineNumber":207,"sourceCode":"                    v = new PROPVARIANT\n                    {\n                        vt = VARTYPE.VT_LPSTR\n                    };\n                    v.union.pszVal = pszVal;\n                }\n                else if (obj is DateTime)\n                {\n                    v = new PROPVARIANT\n                    {\n                        vt = VARTYPE.VT_FILETIME\n                    };\n                    long longFileTime = ((DateTime)obj).ToFileTime();\n                    v.union.filetime.dwLowDateTime = (Int32)longFileTime;\n                    v.union.filetime.dwHighDateTime = (Int32)((longFileTime >> 32) & 0xFFFFFFFF);\n                }\n                else\n                {\n                    throw new InvalidOperationException(\n                        SR.FilterGetValueMustBeStringOrDateTime);\n                }\n\n                // allocate an unmanaged PROPVARIANT to return\n                pNative = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(PROPVARIANT)));\n\n                // Per MSDN, AllocCoTaskMem never returns null: check for IntPtr.Zero instead.\n                Invariant.Assert(pNative != IntPtr.Zero);\n\n                // marshal the managed PROPVARIANT into the unmanaged block and return it\n                Marshal.StructureToPtr(v, pNative, false);\n            }\n            catch\n            {\n                if (pszVal != IntPtr.Zero)\n                {\n                    Marshal.FreeCoTaskMem(pszVal);\n                }","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/indexingfiltermarshaler.cs#L189-L225","documentation":"When a search host calls IFilter::GetValue on a chunk carrying a value, WPF's IndexingFilterMarshaler converts the .NET object returned by GetValue into a native PROPVARIANT. Only string (VT_LPWSTR) and DateTime (VT_FILETIME) have defined conversions here; any other object type falls into the else branch and throws InvalidOperationException (SR.FilterGetValueMustBeStringOrDateTime).","triggerScenarios":"GetValue returns an object that is neither string nor DateTime — e.g., an int, double, bool, Guid, or byte[] exposed as a package property — and the marshaler reaches MarshalPropVariant.","commonSituations":"Indexing an XPS/OPC package whose custom properties contain numeric or boolean values (set via PackageProperties or custom part metadata); a property type changed across versions from string to a typed value; generic object-typed property bags feeding the filter.","solutions":["Ensure GetValue only returns string or DateTime; convert other values with ToString() (or DateTime conversion) before exposing them","Wrap the value provider and pre-coerce unsupported types: numbers/bools to string, dates to DateTime","Avoid storing non-string/non-DateTime values in package properties that will be indexed, or ship a custom IFilter that maps them to PROPVARIANT types"],"exampleFix":"// before\nobject value = 42; // int not supported by MarshalPropVariant\n\n// after\nobject value = 42.ToString(); // string is marshalled as VT_LPWSTR\n// or for dates:\nobject dateValue = ((DateTimeOffset)someDate).UtcDateTime; // DateTime marshalled as VT_FILETIME","handlingStrategy":"validation","validationCode":"if (!(value is string) && !(value is DateTime))\n{\n    value = value?.ToString(); // coerce before the value reaches MarshalPropVariant\n}","typeGuard":"static bool IsFilterValueSupported(object value)\n    => value is string || value is DateTime;","tryCatchPattern":"try\n{\n    IntPtr p = filter.GetValue();\n}\ncatch (InvalidOperationException ex)\n{\n    // value type not marshalable to PROPVARIANT; coerce or skip this property\n    log.Warn(ex.Message);\n}","preventionTips":["Convert numeric/boolean/Guid package properties to strings before exposing them to the filter","Represent timestamps as DateTime so they marshal as VT_FILETIME","Keep property bags that feed indexing constrained to string/DateTime"],"tags":["wpf","com-interop","propvariant","marshalling","packaging"],"backgroundTag":"type-mismatch","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}