QuestPDF/QuestPDF · error · DocumentComposeException

The 'Decoration.Before' layer has already been defined. Plea

Error message

The 'Decoration.Before' layer has already been defined. Please call this method only once.

What it means

A Decoration has three named layers — Before, Content, After — and each may be defined only once. Calling .Before() (or the Before(handler) overload) a second time throws DocumentComposeException because the layer is already populated. Only an Empty or DebugPointer placeholder counts as 'undefined'.

Source

Thrown at src/dotnet/library/QuestPDF/Fluent/DecorationExtensions.cs:27

    public sealed class DecorationDescriptor
    {
        internal Decoration Decoration { get; } = new Decoration();

        internal DecorationDescriptor()
        {
            
        }
        
        /// <summary>
        /// Returns a container for the section positioned before (above) the primary main content.
        /// </summary>
        /// <remarks>
        /// This container is fully visible on each page and does not support paging.
        /// </remarks>
        public IContainer Before()
        {
            if (Decoration.Before is not (Empty or DebugPointer))
                throw new DocumentComposeException("The 'Decoration.Before' layer has already been defined. Please call this method only once.");

            var container = new Container();
            Decoration.Before = container;
            
            return container
                .DebugPointer(DebugPointerType.ElementStructure, "Before")
                .RepeatAsHeader();
        }
        
        /// <summary>
        /// Provides a handler to the section that appears before (above) the main content.
        /// </summary>
        /// <remarks>
        /// This container is fully visible on each page and does not support paging.
        /// </remarks>
        public void Before(Action<IContainer> handler)
        {
            handler?.Invoke(Before());

View on GitHub (pinned to 43ab125596)

Solutions

  1. Define Before exactly once per Decoration; branch the content inside that single call.
  2. If you need conditional header content, build it inside the one Before() lambda.
  3. Search for all .Before( calls on the same decoration instance and consolidate them.

Example fix

// before
decoration.Before().Text("Header");
// later
decoration.Before().Text("Other");  // throws
// after
decoration.Before(b => b.Text(showOther ? "Other" : "Header"));
Defensive patterns

Strategy: validation

Validate before calling

// Structural guard: define Before in exactly one place. If you cannot guarantee that,
// track it with a flag:
bool beforeDefined = false;
if (!beforeDefined) { decoration.Before(b => b.Text(header)); beforeDefined = true; }

Try / catch

try
{
    decoration.Before(b => b.Text(header));
}
catch (DocumentComposeException ex) when (ex.Message.Contains("Decoration.Before"))
{
    // Before was already defined elsewhere; consolidate content instead of calling twice.
    throw;
}

Prevention

When it happens

Trigger: Invoking .Before() twice on the same Decoration container, or calling both .Before() and .Before(handler) on it. The guard checks whether Decoration.Before is anything other than Empty/DebugPointer.

Common situations: Conditional code paths that both call Before; refactoring that merged two setup blocks; copy-paste of a header definition; framework code plus user code both writing Before.

Related errors


AI-assisted analysis of QuestPDF/QuestPDF@43ab125596 (2026-08-13). Data as JSON: /api/errors/6a49e1c29f2777fd. Report an issue: GitHub.