dotnet/wpf · error · InvalidOperationException
Returned string is too long for the buffer provided.
Error message
Returned string is too long for the buffer provided.
What it means
WPF's IndexingFilterMarshaler implements the COM IFilter interface so Windows Search can index XPS/package content. When a host calls IFilter::GetText, MarshalStringToPtr copies the filter's text into a caller-provided character buffer sized by bufCharacterCount. The contract requires room for the string plus a terminating null, so when s.Length > bufCharacterCount - 1 the marshaler throws InvalidOperationException because it can neither truncate the text nor overrun the buffer.
Solutions
- Allocate a buffer of at least (chunk text length + 1) characters before calling GetText and pass that count in bufCharacterCount
- Catch the exception, grow the buffer, and retry the GetText call
- If you control the filter's text source, split long strings so each fits the advertised buffer size
- Verify the host counts characters (WCHARs), not bytes — a byte/char confusion makes buffers appear half-size
Example fix
// before: fixed 64-char buffer regardless of text char[] buf = new char[64]; uint count = 64; filter.GetText(ref count, buf); // after: size the buffer for the chunk text plus terminating null string text = chunk.Text; char[] buf = new char[text.Length + 1]; uint count = (uint)buf.Length; filter.GetText(ref count, buf);
Defensive patterns
Strategy: try-catch
Validate before calling
if (text != null && bufCharacterCount < (uint)text.Length + 1)
{
// grow the buffer before calling GetText
bufCharacterCount = (uint)text.Length + 1;
buffer = new char[text.Length + 1];
} Try / catch
try
{
filter.GetText(ref bufCharacterCount, buffer);
}
catch (InvalidOperationException ex)
{
// string did not fit: enlarge buffer to text length + 1 and retry
GrowBufferAndRetry();
} Prevention
- Size buffers in characters (WCHARs), never bytes
- Always reserve one extra character for the terminating null
- Use a grow-and-retry loop pattern around GetText instead of assuming a fixed buffer size
When it happens
Trigger: A search/indexing host calls GetText with a buffer whose bufCharacterCount is less than or equal to the length of the current text chunk string; the check (uint)s.Length > bufCharacterCount - 1 in MarshalStringToPtr fires.
Common situations: Custom IFilter hosts or third-party indexing clients that allocate undersized text buffers when enumerating an XPS document via WPF's filter; hosts that pass bufCharacterCount in bytes instead of characters, halving the effective capacity; buffer-size renegotiation bugs after partial GetText calls.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- E_NOTIMPL
- FILTER_E_END_OF_CHUNKS
- Only string and DateTime types are supported for…
- ' ' cannot contain the path delimiter: ' '.
- ' ' cannot start with the reserved character range…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3d3cb7b02c885245.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/indexingfiltermarshaler.cs:98
return null;
}
/// <summary>
/// StringToPtr
/// </summary>
/// <remarks>Converts a managed string into the format useful for IFilter.GetText</remarks>
/// <param name="s">string to convert</param>
/// <param name="bufCharacterCount">maximum number of characters to convert</param>
/// <param name="p">pointer to write to</param>
internal static void MarshalStringToPtr(string s, ref uint bufCharacterCount, IntPtr p)
{
// bufCharacterCount is never supposed to be zero at this level.
Invariant.Assert(bufCharacterCount != 0);
// ensure the interface rules are followed
// string must also be null terminated so we restrict the length to buf size - 1
if ((uint)(s.Length) > bufCharacterCount - 1)
throw new InvalidOperationException(SR.FilterGetTextBufferOverflow);
// Return the number of characters written, including the terminating null.
bufCharacterCount = (UInt32)s.Length + 1;
// convert string to unmanaged string and write into provided buffer
Marshal.Copy(s.ToCharArray(), 0, p, s.Length);
// null terminate (16bit's of zero to replace one Unicode character)
Marshal.WriteInt16(p, s.Length * _int16Size, 0);
}
/// <summary>
/// Marshal Managed to Native PROPSPEC
/// </summary>
/// <param name="propSpec"></param>
/// <param name="native"></param>
internal static void MarshalPropSpec(ManagedPropSpec propSpec, ref PROPSPEC native)
{View on GitHub (pinned to 81131a70a4)