{"record":{"id":"3e7f399becc5f542","repo":"dotnet/wpf","slug":"invalid-ep-in-isf","errorCode":null,"errorMessage":"Invalid EP in ISF","messagePattern":"Invalid EP in ISF","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/CustomAttributeSerializer.cs","lineNumber":292,"sourceCode":"                        bw.Write((byte)0);\n                    }\n                    break;\n                }\n                case (VarEnum.VT_DECIMAL)://14\n                {\n                    decimal data = (decimal)value;\n                    bw.Write(data);\n                    break;\n                }\n                case (VarEnum.VT_BSTR)://8\n                {\n                    string data = (string)value;\n                    bw.Write( System.Text.Encoding.Unicode.GetBytes( data ) );\n                    break;\n                }\n                default:\n                {\n                    throw new InvalidOperationException(SR.InvalidEpInIsf);\n                }\n            }\n        }\n#if OLD_ISF\n        /// <summary>\n        /// Encodes a custom attribute to the ISF stream\n        /// </summary>\n#else\n        /// <summary>\n        /// Encodes a custom attribute to the ISF stream\n        /// </summary>\n#endif\n        internal static uint EncodeAsISF(Guid id, byte[] data, Stream strm, GuidList guidList, byte compressionAlgorithm, bool fTag)\n        {\n            uint cbWrite = 0;\n            uint cbSize = GuidList.GetDataSizeIfKnownGuid(id);\n            Debug.Assert(strm != null);\n","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/CustomAttributeSerializer.cs#L274-L310","documentation":"Thrown by CustomAttributeSerializer.EncodeAttribute when encoding an ExtendedProperty whose value is of a type that has no ISF serialization rule (the switch over the value's Type fell through to the default case). ISF can only encode known value types (uint/int/byte[], string, etc.); anything else cannot be written to the stream. The library treats this as a programming/data error rather than an environment failure.","triggerScenarios":"Calling StrokeCollection/Stroke DrawingAttributes or ExtendedProperties save path (Save/EncodeToStream) with a custom extended property whose value type is not one of the ISF-supported types (e.g. a custom class, DateTime, or double not handled by the encoder).","commonSituations":"Storing arbitrary user objects in Stroke.ExtendedProperties or DrawingAttributes.ExtendedProperties and then serializing the ink to ISF (InkCanvas Save, StrokeCollection.Save with format ISF); code that worked with GIF persistence breaks when switching to ISF where type support is stricter.","solutions":["Find the extended property whose value type is unsupported and remove it before saving, or convert its value to a supported type (int, uint, string, byte[]).","Ensure the value's runtime Type exactly matches one handled by the serializer (e.g. box an int as int, not a convertible double).","If persistence of complex objects is required, serialize the object to a byte[] or string yourself and store that in the extended property.","Persist in GIF instead of ISF if you need extended properties that ISF cannot encode, or keep custom data outside the ink stream."],"exampleFix":"// before\nstroke.ExtendedProperties.Add(\"http://example.com/mydata\", new MyCustomObject());\nstrokeCollection.Save(stream, PersistenceFormat.InkSerializedFormat);\n// after\nstroke.ExtendedProperties.Add(\"http://example.com/mydata\", Convert.ToBase64String(SerializeToBytes(myObj)));\nstrokeCollection.Save(stream, PersistenceFormat.InkSerializedFormat);","handlingStrategy":"validation","validationCode":"bool IsIsfEncodable(object v) => v is int || v is uint || v is byte || v is byte[] || v is string || v is float || v is double || v is System.Windows.Media.Color;\nif (!IsIsfEncodable(value)) throw new ArgumentException($\"Value type {value.GetType()} is not ISF-encodable\");","typeGuard":"bool IsIsfEncodable(object v) => v is int or uint or byte or byte[] or string or float or double or System.Windows.Media.Color;","tryCatchPattern":null,"preventionTips":["Only store primitive ISF-supported types in ExtendedProperties before ISF saves","Serialize complex objects to byte[] or string yourself","Test ink Save/Load round-trips with all extended properties you register"],"tags":["ink","isf","serialization","unsupported-type"],"backgroundTag":"unsupported-enum-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}