{"record":{"id":"663c88329a8a1176","repo":"dotnet/wpf","slug":"stroke-custom-attribute-tag-embedded-in-isf-stream-does-not","errorCode":null,"errorMessage":"Stroke Custom Attribute tag embedded in ISF stream does not match guid table","messagePattern":"Stroke Custom Attribute tag embedded in ISF stream does not match guid table","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs","lineNumber":306,"sourceCode":"\n                                byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);\n\n                                System.Diagnostics.Debug.Fail(\"ExtendedProperties for points are not supported\");\n\n                                // skip the bytes in both success & failure cases\n                                // Note: Point ExtendedProperties are discarded\n                                remainingBytesInStrokeBlock -= propsize;\n                            }\n                        }\n                        break;\n\n                    default:\n                        {\n                            object data;\n                            Guid guid = guidList.FindGuid(tag);\n                            if (guid == Guid.Empty)\n                            {\n                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Stroke Custom Attribute tag embedded in ISF stream does not match guid table\"));\n                            }\n\n                            // load the extended property data from the stream (and decode the type)\n                            locallyDecodedBytes = ExtendedPropertySerializer.DecodeAsISF(stream, remainingBytesInStrokeBlock, guidList, tag, ref guid, out data);\n\n                            // add the guid/data pair into the property collection (don't redecode the type)\n                            if (extendedProperties == null)\n                            {\n                                extendedProperties = new ExtendedPropertyCollection();\n                            }\n                            extendedProperties[guid] = data;\n                            if (locallyDecodedBytes > remainingBytesInStrokeBlock)\n                            {\n                                throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage(\"ExtendedProperty decoded totalBytesInStrokeBlockOfIsfStream exceeded ISF stream totalBytesInStrokeBlockOfIsfStream\"));\n                            }\n\n                            remainingBytesInStrokeBlock -= locallyDecodedBytes;\n                        }","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs#L288-L324","documentation":"Thrown by StrokeSerializer.DecodeISFIntoStroke when a custom-attribute tag read from the ISF stream cannot be resolved to a Guid via the GuidList (guid table). Every embedded extended property tag must map to a known GUID; an unmapped tag means the stream was produced by an unknown/incompatible ISF writer or is corrupt.","triggerScenarios":"Deserializing ISF that contains stroke extended-property tags not present in the reader's GUID table (ISF from other vendors, proprietary extensions, or bit-corrupted tag values) via StrokeCollection.Deserialize.","commonSituations":"Round-tripping ink between different vendors' ink SDKs; loading ISF written by newer WPF versions carrying GUIDs unknown to an older reader; corrupted tag bytes in damaged files.","solutions":["Load the ISF with a runtime/version that recognizes the tag's GUID, or upgrade to the newest WPF/System.Windows.Ink implementation","Strip unknown extended properties before saving so only well-known GUID tags are embedded","Use DrawAttributes/extended properties only with GUIDs from KnownValues/AnalysisCore GUID tables when targeting cross-version ISF","Catch ArgumentException, and re-persist the ink from the in-memory StrokeCollection (losing the unknown property)","Inspect the ISF with a hex dump to identify the offending tag and confirm the producer application"],"exampleFix":"// before\nstroke.AddPropertyData(customVendorGuid, data); // unknown to other readers' guid table\n// after\nif (KnownValues.GetAllKnownGuids().Contains(customVendorGuid))\n    stroke.AddPropertyData(customVendorGuid, data); // only embed known GUIDs","handlingStrategy":"try-catch","validationCode":"// Restrict embedded extended properties to known GUIDs before saving\nstatic bool IsKnownGuid(Guid g) =>\n    g == KnownValues.StrokeExtendedPropertyGuid || /* ...other known GUIDs... */ false;\n// filter: keep only strokes whose ExtendedProperties keys are known","typeGuard":null,"tryCatchPattern":"try { scs.Deserialize(stream); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"does not match guid table\")) {\n    log.Warn(\"Unknown ISF custom-attribute tag\", ex);\n    // re-persist ink from object model without unknown properties\n}","preventionTips":["Only embed extended properties with GUIDs from the known GUID table when cross-version compatibility matters","Avoid round-tripping ISF between different vendors' ink SDKs","Version-tag your ink files so unknown producers can be detected before load"],"tags":["ink","isf","deserialization","guid","compatibility"],"backgroundTag":"invalid-identifier-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}