dotnet/wpf · error · InvalidOperationException
Only string and DateTime types are supported for…
Error message
Only string and DateTime types are supported for marshalling to PROPVARIANT.
What it means
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).
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
Example fix
// before object value = 42; // int not supported by MarshalPropVariant // after object value = 42.ToString(); // string is marshalled as VT_LPWSTR // or for dates: object dateValue = ((DateTimeOffset)someDate).UtcDateTime; // DateTime marshalled as VT_FILETIME
Defensive patterns
Strategy: validation
Validate before calling
if (!(value is string) && !(value is DateTime))
{
value = value?.ToString(); // coerce before the value reaches MarshalPropVariant
} Type guard
static bool IsFilterValueSupported(object value)
=> value is string || value is DateTime; Try / catch
try
{
IntPtr p = filter.GetValue();
}
catch (InvalidOperationException ex)
{
// value type not marshalable to PROPVARIANT; coerce or skip this property
log.Warn(ex.Message);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
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
- Returned string is too long for the buffer provided.
- ' ' cannot contain the path delimiter: ' '.
- ' ' cannot start with the reserved character range…
- ' ' ID is not a valid XSD ID.
- 0x80040206
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/6c1899c9bed42fab.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/indexingfiltermarshaler.cs:207
v = new PROPVARIANT
{
vt = VARTYPE.VT_LPSTR
};
v.union.pszVal = pszVal;
}
else if (obj is DateTime)
{
v = new PROPVARIANT
{
vt = VARTYPE.VT_FILETIME
};
long longFileTime = ((DateTime)obj).ToFileTime();
v.union.filetime.dwLowDateTime = (Int32)longFileTime;
v.union.filetime.dwHighDateTime = (Int32)((longFileTime >> 32) & 0xFFFFFFFF);
}
else
{
throw new InvalidOperationException(
SR.FilterGetValueMustBeStringOrDateTime);
}
// allocate an unmanaged PROPVARIANT to return
pNative = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(PROPVARIANT)));
// Per MSDN, AllocCoTaskMem never returns null: check for IntPtr.Zero instead.
Invariant.Assert(pNative != IntPtr.Zero);
// marshal the managed PROPVARIANT into the unmanaged block and return it
Marshal.StructureToPtr(v, pNative, false);
}
catch
{
if (pszVal != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pszVal);
}View on GitHub (pinned to 81131a70a4)