diff --git a/src/UglyToad.PdfPig/Content/OptionalContentGroupElement.cs b/src/UglyToad.PdfPig/Content/OptionalContentGroupElement.cs index bcc0eb52a..c7cd6c242 100644 --- a/src/UglyToad.PdfPig/Content/OptionalContentGroupElement.cs +++ b/src/UglyToad.PdfPig/Content/OptionalContentGroupElement.cs @@ -59,7 +59,10 @@ internal OptionalContentGroupElement(MarkedContentElement markedContentElement, switch (Type) { case "OCG": // Optional content group dictionary - // Name - Required + // Name - Per spec this is required, but in practice some PDFs store layer names + // at the document catalog level in OCProperties rather than in marked content Properties. + // To avoid crashes, we make this optional and fall back to null or the tag name. + if (markedContentElement.Properties.TryGet(NameToken.Name, pdfTokenScanner, out NameToken? name)) { Name = name.Data; @@ -74,7 +77,9 @@ internal OptionalContentGroupElement(MarkedContentElement markedContentElement, } else { - throw new ArgumentException($"Cannot parse optional content's {nameof(Name)} from {nameof(markedContentElement.Properties)}. This is a required field.", nameof(markedContentElement.Properties)); + // Name not found in Properties - use tag as fallback or leave as null + // This handles PDFs where layer names are stored at document catalog level + Name = markedContentElement.Tag; } // Intent - Optional