{"record":{"id":"fe80006bb1ee2c1e","repo":"AvaloniaUI/Avalonia","slug":"pathmarkupparser","errorCode":null,"errorMessage":"PathMarkupParser","messagePattern":"PathMarkupParser","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Media/PathMarkupParser.cs","lineNumber":614,"sourceCode":"                command = default;\n                relative = false;\n                return false;\n            }\n            var c = span[0];\n            if (!s_commands.TryGetValue(char.ToUpperInvariant(c), out command))\n            {\n                throw new InvalidDataException(\"Unexpected path command '\" + c + \"'.\");\n            }\n            relative = char.IsLower(c);\n            span = span.Slice(1);\n            return true;\n        }\n\n        [MemberNotNull(nameof(_geometryContext))]\n        private void ThrowIfDisposed()\n        {\n            if (_isDisposed || _geometryContext is null)\n                throw new ObjectDisposedException(nameof(PathMarkupParser));\n        }\n    }\n}\n","sourceCodeStart":596,"sourceCodeEnd":618,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Media/PathMarkupParser.cs#L596-L618","documentation":"Thrown by ThrowIfDisposed (called from Parse, SetFillRule, CreateFigure, and every Add* method) when the parser has already been disposed or its _geometryContext has been nulled. Dispose(true) sets _isDisposed and nulls _geometryContext, so any subsequent use is rejected.","triggerScenarios":"Calling parser.Parse(...) after the parser was disposed (e.g. after leaving a 'using var parser = ...' block), or reusing a parser whose owning geometry context was closed/disposed.","commonSituations":"Using the parser inside a using block and then calling Parse again outside it; sharing a parser field across operations where one path disposes it; nesting geometry Open()/Dispose() scopes incorrectly.","solutions":["Create a fresh PathMarkupParser per parse operation rather than reusing a disposed instance.","Make sure the using/Dispose scope encloses all Parse calls you need.","Do not dispose the StreamGeometryContext before finishing all writes through the parser."],"exampleFix":"// before\nusing (var parser = new PathMarkupParser(ctx))\n{\n    parser.Parse(first);\n}\nparser.Parse(second); // throws ObjectDisposedException\n\n// after\nforeach (var data in new[] { first, second })\n{\n    using var parser = new PathMarkupParser(ctx);\n    parser.Parse(data);\n}","handlingStrategy":"validation","validationCode":"if (parser is IDisposable { } d) { /* don't reuse after dispose */ }\n// Track a _disposed flag in your own code and re-create the parser per parse.","typeGuard":null,"tryCatchPattern":"try { parser.Parse(data); }\ncatch (ObjectDisposedException) { /* re-create parser + context and retry once */ }","preventionTips":["Scope each parser to a single Parse() call inside a using block.","Never share a disposed parser across operations.","Keep the owning StreamGeometryContext open for the full lifetime of the parser."],"tags":["avalonia","path-markup","disposed","objectdisposed","lifecycle"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}