ContentRepository.Save throws EpiserverCancelException with empty reason when creating page via addon

Vote:
 

Hi everyone,

I’m working on a custom Optimizely CMS plugin/addon that programmatically creates a new page based on an existing source page and saves it using IContentRepository.Save().

We using the addon from our main project, the save fails with an exception:

Episerver.Core.EpiserverCancelException
Reason: \r\n

Unfortunately, the reason is completely empty, which makes it very hard to diagnose what’s actually blocking the save.

Here’s a simplified version of the code:

if (ContentReference.IsNullOrEmpty(targetPageRef))
{
    var newPage = _contentRepository
        .GetDefault<PageData>(
            targetParentRef,
            sourcePage.ContentTypeID,
            sourcePage.Language)
        .SetDefaultPageValues(sourcePage);

    newPage = newPage
        .UpdateRequiredFields(sourcePage)
        .SetDisabledProperties();

    _logger.LogInformation(
        "Created new page from '{ContentLink}'",
        sourcePage.ContentLink.ID);

    try
    {
        var saveAction = newPage.HasRequiredFields()
            ? GetSaveAction(sourcePage)
            : SaveAction.SkipValidation | SaveAction.CheckOut;

        targetPageRef = _contentRepository.Save(
            newPage,
            saveAction,
            AccessLevel.NoAccess);
    }
    catch (Exception ex)
    {
        _logger.LogError(
            ex,
            "Error saving new page '{PageName}' under parent '{ParentId}'",
            newPage.Name,
            targetParentRef.ID);
        throw;
    }
}

My questions:

  • What typically causes an EpiserverCancelException with an empty reason?

  • Are there common CMS events, validators, or content handlers that silently cancel saves?

  • Is there a way to surface which validation or event handler is causing the cancellation?

  • Any known pitfalls when saving content from addons/plugins vs. site code?

Any pointers, debugging tips, or similar experiences would be hugely appreciated 🙏
Thanks in advance!

Thanks, Jakob

#341666
Feb 11, 2026 14:36
Vote:
 

Can you catch the exception and look into it?

e.g

catch (EPiServerCancelException ex)
{
    _logger.LogError(ex,
        "Save cancelled. User={User}, Parent={Parent}, Type={Type}, Lang={Lang}", // or something like that
        PrincipalInfo.CurrentPrincipal?.Identity?.Name,
        targetParentRef?.ID,
        sourcePage.ContentTypeID,
        sourcePage.Language?.Name);
    // debug from here
    throw;
}

Also turn on Optimizely debug logging for content/events. That probably would be debug level on  EPiServer, EPiServer.Core and EPiServer.DataAccess

This would be done in appsettings.json, e.g.

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning",
      "EPiServer": "Debug",
      "EPiServer.Core": "Debug",
      "EPiServer.DataAccess": "Debug"
    }
  },
#341671
Edited, Feb 12, 2026 7:32
Jakob Lystbæk - Feb 12, 2026 9:40
Hi, thank you for your answer. I don't know how to turn on Optimizely debug logging for content/events. Do you know of relevant documentation?
Eric Herlitz - Feb 12, 2026 9:58
Hi, updated the answer with a config example in appsettings.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.