AvaloniaUI/Avalonia · error · ObjectDisposedException
PathMarkupParser
Error message
PathMarkupParser
What it means
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.
Source
Thrown at src/Avalonia.Base/Media/PathMarkupParser.cs:614
command = default;
relative = false;
return false;
}
var c = span[0];
if (!s_commands.TryGetValue(char.ToUpperInvariant(c), out command))
{
throw new InvalidDataException("Unexpected path command '" + c + "'.");
}
relative = char.IsLower(c);
span = span.Slice(1);
return true;
}
[MemberNotNull(nameof(_geometryContext))]
private void ThrowIfDisposed()
{
if (_isDisposed || _geometryContext is null)
throw new ObjectDisposedException(nameof(PathMarkupParser));
}
}
}
View on GitHub (pinned to 11c5427268)
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.
Example fix
// before
using (var parser = new PathMarkupParser(ctx))
{
parser.Parse(first);
}
parser.Parse(second); // throws ObjectDisposedException
// after
foreach (var data in new[] { first, second })
{
using var parser = new PathMarkupParser(ctx);
parser.Parse(data);
} Defensive patterns
Strategy: validation
Validate before calling
if (parser is IDisposable { } d) { /* don't reuse after dispose */ }
// Track a _disposed flag in your own code and re-create the parser per parse. Try / catch
try { parser.Parse(data); }
catch (ObjectDisposedException) { /* re-create parser + context and retry once */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/fe80006bb1ee2c1e.
Report an issue: GitHub.