dotnet/wpf · error · XpsPackagingException
PrintTicket was already committed.
Error message
PrintTicket was already committed.
What it means
XpsPackagingException thrown from the PrintTicket setter of XpsFixedPageReaderWriter when PrintTicket is set a second time after it has already been committed to the package. The XPS writer model allows a page's PrintTicket to be assigned exactly once; after commit it is written as a part and the assignment is immutable. This enforces package consistency between the page and its ticket part.
Solutions
- Set PrintTicket exactly once per page reader, before Commit()ing the page.
- If the ticket must change, create a new page (or a new document) and write it with the corrected ticket instead of reassigning.
- Restructure code so the final ticket is computed before the first assignment (e.g. resolve defaults up front).
- Track commitment state in your own code (bool ticketSet) to guard reassignment.
- Wrap in try-catch for XpsPackagingException to detect double-commit during batch generation.
Example fix
// before pageWriter.PrintTicket = defaultTicket; if (userOverride != null) pageWriter.PrintTicket = userOverride; // throws // after PrintTicket final = userOverride ?? defaultTicket; pageWriter.PrintTicket = final; // set once pageWriter.Commit();
Defensive patterns
Strategy: validation
Validate before calling
// Guard before assigning
bool canSetTicket = true; // track locally
if (ticketAlreadySet.ContainsKey(pageWriter))
throw new InvalidOperationException("PrintTicket already committed for this page");
// else assign once and record
pageWriter.PrintTicket = ticket;
ticketAlreadySet[pageWriter] = true; Try / catch
try
{
pageWriter.PrintTicket = finalTicket;
}
catch (XpsPackagingException ex) when (ex.Message.Contains("already committed"))
{
log.Warn("PrintTicket reassignment ignored; first ticket retained.");
} Prevention
- Assign PrintTicket exactly once per page, computing the final value before the first set.
- Centralize ticket assignment in a single SetPageTicket helper that tracks state.
- Never set the ticket in retry loops; recreate the page on retry instead.
- Commit pages only after the ticket is final.
When it happens
Trigger: Assigning the PrintTicket property twice on an IXpsFixedPageReaderWriter where the first assignment completed the commit — typically pageReader.PrintTicket = ticket; ...; pageReader.PrintTicket = otherTicket; while writing an XPS document.
Common situations: Code paths that retry page writing and reassign the ticket on a retry; loops that set defaults for all pages and then set page-specific tickets; frameworks that set a ticket per-property-update.
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
- PackagePart has more than one Print Ticket relationship.
- PrintTicket was already committed.
- Property is not a valid instance of PrintTicket.
- Property is not a valid instance of PrintTicket.
- ReachPackaging_NotAPrintTicket
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/c8c7f797f1de9247.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedPageReaderWriter.cs:509
/// <exception cref="SR.ReachPackaging_PrintTicketAlreadyCommitted">part is null.</exception>
/// <exception cref="SR.ReachPackaging_NotAPrintTicket">part is null.</exception>
public PrintTicket PrintTicket
{
get
{
if( _printTicket == null )
{
_printTicket = CurrentXpsManager.EnsurePrintTicket( Uri );
}
return _printTicket;
}
set
{
if(value != null)
{
if (_isPrintTicketCommitted)
{
throw new XpsPackagingException(SR.ReachPackaging_PrintTicketAlreadyCommitted);
}
if (!value.GetType().Equals(typeof(PrintTicket)))
{
throw new XpsPackagingException(SR.ReachPackaging_NotAPrintTicket);
}
_printTicket = value.Clone();
}
else
{
_printTicket = null;
}
}
}
/// <summary>
/// Gets a reference to the XmlWriter for the Metro part
/// that represents this fixed page within the package.View on GitHub (pinned to 81131a70a4)