dotnet/wpf · error · COMException

0x8004020a

0x8004020a

Error message

SR.TextStore_TS_E_FORMAT

What it means

When compiled with ENABLE_INK_EMBEDDING, InsertEmbedded requires the text selection to have a concrete text container (TextSelection.HasConcreteTextContainer); if not, it throws COMException TS_E_FORMAT (0x8004020a) because the target cannot accept embedded-object format. Without that build flag the same call path throws TS_E_FORMAT unconditionally (see 2869).

Solutions

  1. Do not attempt embedded-object insertion into WPF text controls; TS_E_FORMAT indicates unsupported format.
  2. Convert the content to plain text and use SetText/InsertTextAtSelection instead.
  3. Catch COMException with HRESULT TS_E_FORMAT and fall back to plain-text insertion.

Example fix

// before
store.InsertEmbedded(flags, start, end, dataObject, out change);
// after: fall back to text
store.SetText(flags, start, end, textChars, textChars.Length, out change);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!TextSelection.HasConcreteTextContainer) { /* target cannot accept embedded format; use text instead */ }

Try / catch

try { store.InsertEmbedded(...); } catch (COMException ex) when (ex.ErrorCode == unchecked((int)0x8004020a)) { /* fall back to plain text insert */ }

Prevention

When it happens

Trigger: InsertEmbedded called when the TextSelection does not back a concrete TextContainer (e.g. non-concrete/virtual selection), inside the ENABLE_INK_EMBEDDING code path.

Common situations: TSF clients inserting embedded objects into WPF selections that do not represent an editable RichTextBox-style document (ink embedding is effectively disabled in WPF).

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextStore.cs:613

            {
                insertable = false;
            }
#endif
        }

        // See msdn's ITextStoreACP documentation for a full description.
        public void InsertEmbedded(UnsafeNativeMethods.InsertEmbeddedFlags flags, int startIndex, int endIndex, object obj, out UnsafeNativeMethods.TS_TEXTCHANGE change)
        {
            if (IsReadOnly)
            {
                throw new COMException(SR.TextStore_TS_E_READONLY, UnsafeNativeMethods.TS_E_READONLY);
            }

            // Disable embedded object temporarily.
#if ENABLE_INK_EMBEDDING
            if (!TextSelection.HasConcreteTextContainer)
            {
                throw new COMException(SR.TextStore_TS_E_FORMAT, UnsafeNativeMethods.TS_E_FORMAT);
            }

            TextContainer container;
            TextPointer startPosition;
            TextPointer endPosition;
            IComDataObject data;

            // The object must have IOldDataObject internface.
            // The obj param of InsertEmbedded is IDataObject in Win32 definition.
            data = obj as IComDataObject;
            if (data == null)
            {
                throw new COMException(SR.TextStore_BadObject, NativeMethods.E_INVALIDARG);
            }

            container = (TextContainer)this.TextContainer;

            startPosition = container.CreatePointerAtOffset(startIndex, LogicalDirection.Backward);

View on GitHub (pinned to 81131a70a4)