dotnet/wpf · error · InvalidOperationException

InvalidEpInIsf

Error message

InvalidEpInIsf

What it means

Thrown by ExtendedPropertySerializer.DecodeAttribute inside CustomAttributeSerializer when decoding an extended property value whose tag corresponds to a data type the decoder does not handle (default case of the tag switch). The ISF tag says the value is of a type this decoder cannot produce, so it refuses rather than return garbage.

Solutions

  1. Identify the extended property with the unsupported tag in the source ink and remove/convert it to a supported type before saving.
  2. Re-save the ink with a writer that emits only WPF-supported extended property types.
  3. Load the ink in the same version/platform that wrote it, or upgrade to a version supporting the tag.
  4. If the property is optional, tolerate the failure by catching the exception and skipping that attribute during load.

Example fix

// before
strokeCollection.Load(isfStream); // throws on unsupported extended property tag
// after
try { strokeCollection.Load(isfStream); }
catch (ArgumentException) { isfStream.Position = 0; LoadStrippingUnknownProperties(isfStream); }
Defensive patterns

Strategy: try-catch

Try / catch

try { strokeCollection.Load(isfStream); }
catch (ArgumentException ex)
{
    Log.Warn("Unsupported ISF extended property tag", ex);
    // retry with stripped/converted extended properties
}

Prevention

When it happens

Trigger: Loading ISF ink that contains an extended property encoded with a tag type unsupported by this version's decoder — e.g. data written by a newer or non-WPF ISF implementation using tags this code path doesn't recognize.

Common situations: Round-tripping ink between different platforms/versions of ISF writers; ink files created by tablet/ink SDKs with richer extended-property types than WPF supports.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/CustomAttributeSerializer.cs:686

                        return br.ReadUInt64();
                    case (VarEnum.VT_R4):
                        return br.ReadSingle();
                    case (VarEnum.VT_R8):
                        return br.ReadDouble();
                    case (VarEnum.VT_DATE):
                        return DateTime.FromOADate(br.ReadDouble());
                    case (VarEnum.VT_BOOL):
                        return br.ReadBoolean();
                    case (VarEnum.VT_DECIMAL):
                        return br.ReadDecimal();
                    case (VarEnum.VT_BSTR):
                        {
                            byte[] bytestring = br.ReadBytes((int)memStream.Length);
                            return System.Text.Encoding.Unicode.GetString(bytestring);
                        }
                    default:
                        {
                            throw new InvalidOperationException(SR.InvalidEpInIsf);
                        }
                }
            }
        }
#if OLD_ISF
        /// <summary>
        /// Saves all elements in this list in the stream passed with the tags being generated based on the GuidList
        /// by the caller and using compressionAlgorithm as the preferred algorith identifier. For ExtendedPropertyCollection associated
        /// with Ink, drawing attributes and Point properties, we need to write the tag while saving them and hence
        /// fTag param is true. For strokes, the Tag is stored in the stroke descriptor and hence we don't store the
        /// tag
        /// </summary>
        /// <param name="attributes">Custom attributes to encode</param>
        /// <param name="stream">If stream is null, then size is calculated only.</param>
        /// <param name="guidList"></param>
        /// <param name="compressionAlgorithm"></param>
        /// <param name="fTag"></param>
        /// <returns></returns>

View on GitHub (pinned to 81131a70a4)