dotnet/wpf · error · ObjectDisposedException
FixedPageReader
Error message
FixedPageReader
What it means
ObjectDisposedException thrown by XpsFixedPageReaderWriter.AddResource when the page's underlying package part (_metroPart) is null, meaning the FixedPage reader/writer has been disposed (or was never backed by a part). You cannot add resources (images, fonts, etc.) to a page after its part has gone away.
Solutions
- Call AddResource before Commit()/Dispose of the page writer.
- Reorder code so resources (fonts, images) are added while the page is open, then commit last.
- Keep the XpsDocument open until all page resources are written.
- Remove stale page-writer references once the document is closed; reacquire readers via the document if needed.
- Wrap in try-catch for ObjectDisposedException to surface lifecycle bugs during batch generation.
Example fix
// before page.Commit(); page.AddResource(typeof(XpsImage), imageUri); // throws // after page.AddResource(typeof(XpsImage), imageUri); page.Commit();
Defensive patterns
Strategy: try-catch
Validate before calling
// Track lifecycle: only call while page is open
if (pageCommitted) throw new InvalidOperationException("Page already committed; AddResource is invalid");
// else safe:
pageWriter.AddResource(typeof(XpsImage), imageUri); Type guard
bool CanMutatePage(IXpsFixedPageReaderWriter page) => page != null && !isCommitted.Contains(page);
Try / catch
try
{
pageWriter.AddResource(resourceType, resourceUri);
}
catch (ObjectDisposedException ex) when (ex.ObjectName == "FixedPageReader")
{
throw new InvalidOperationException("Resources must be added before page Commit(). Reorder the pipeline.", ex);
} Prevention
- Add all resources (images, fonts, etc.) before calling Commit() on the page.
- Keep the XpsDocument open until every page resource is written.
- Don't cache page-writer references past document close; reacquire via the document instead.
- Structure generation as: open page -> add resources -> set ticket -> commit.
When it happens
Trigger: Calling AddResource(Type resourceType, Uri resourceUri) after Commit()ing or disposing the page writer, or on a reader obtained from a closed/disposed XpsDocument.
Common situations: Retaining IXpsFixedPageReaderWriter references in collections after the document was closed; adding resources in a deferred/background step that runs after page commit; using statements that dispose the XpsDocument before resource attachment finishes.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- CurrentFixedPageWriter uninitialized
- SR.ByteRangeDownloaderDisposed
- SR.ReachSerialization_NoFixedPageWriter
- SR.StorageRootDisposed
- SR.XpsSerializerFactory_WriterIsClosed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/81b7974d588e57b4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedPageReaderWriter.cs:781
/// </param>
/// <param name="resourceUri">
/// The absolute path to the resouce to be added. If null
/// a unique resource path will be generated
/// </param>
/// <returns>
/// Returns an XpsResource instance for the newly created resource.
/// </returns>
/// <exception cref="ObjectDisposedException">FixedPageReader has already been disposed</exception>
public
XpsResource
AddResource(
Type resourceType,
Uri resourceUri
)
{
if (null == _metroPart)
{
throw new ObjectDisposedException("FixedPageReader");
}
//
// Create the part and writer
//
PackagePart metroPart = null;
if( resourceUri != null )
{
metroPart = this.CurrentXpsManager.GetPart(resourceUri);
if (metroPart == null)
{
metroPart = GeneratePartForResourceType(resourceType, resourceUri);
}
}
XpsResource xpsResource;
if( resourceType == typeof( XpsImage ) )
{View on GitHub (pinned to 81131a70a4)