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.
Vote:
 

Can you run this in debug mode and look into the inner exception if any?

If debugging is not an option, your catch could try to see if ex.InnerException has anything 

#341858
Mar 05, 2026 9:10
Vote:
 

My gut feeling was some code (yours or some third parties) are listening to IContentSecurityEvents.ContentSecuritySaving and cancel the saving. Could you find anything in your solution 

#341861
Mar 05, 2026 9:27
* 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.