Initialization exception after removing content type

Hi!

I removed a content type from my solution and in my local environment runs just fine, also in our test environment. But when I try to run it in our UAT environment I get the exception below on startup at the site wont run. Any ideas what could be causing this?
Seems like Optimizely tries to delete the content type from the db, I thought Opti never deleted anything? 

Exception: 
EPiServer.Framework.Initialization.InitializationException: Initialize action failed for Initialize on class EPiServer.Initialization.Internal.ModelSyncInitialization, EPiServer, Version=12.22.2.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_tblContentSoftlink_tblPropertyDefinition". The conflict occurred in database "database_utb", table "dbo.tblContentSoftlink", column 'fkOwnerPropertyDefinitionID'.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, SqlCommand command, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at Microsoft.Data.SqlClient.SqlDataReader.get_MetaData()
   at Microsoft.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean isAsync, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
   at EPiServer.DataAccess.Internal.ContentTypeDB.<>c__DisplayClass43_0.<DeleteDB>b__0()
   at EPiServer.Data.Providers.Internal.SqlDatabaseExecutor.<>c__DisplayClass28_0`1.<ExecuteTransaction>b__0()
   at EPiServer.Data.Providers.SqlTransientErrorsRetryPolicy.Execute[TResult](Func`1 method)
   at EPiServer.Data.Providers.Internal.SqlDatabaseExecutor.ExecuteTransaction[TResult](Func`1 action)
   at EPiServer.DataAccess.Internal.ContentTypeDB.DeleteDB(Int32 pageTypeID)
   at EPiServer.DataAccess.Internal.ContentTypeDB.Delete(ContentType contentType)
   at EPiServer.DataAbstraction.Internal.DefaultContentTypeRepository.Delete(ContentType contentType)
   at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeSynchronizer.Delete(ContentType contentType)
   at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.CommitTypes(Boolean deleteUnusedTypes)
   at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.Sync(Boolean forceCommit)
   at EPiServer.Initialization.Internal.ModelSyncInitialization.Initialize(InitializationEngine context)
   at EPiServer.Framework.Initialization.Internal.ModuleNode.<>c__DisplayClass4_0.<Initialize>b__0()
   at EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key)
   at EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context)
   at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
ClientConnectionId:7f837737-6f96-408a-9c96-679b440bb4fb
Error Number:547,State:0,Class:16
   --- End of inner exception stack trace ---
   at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
   at EPiServer.Framework.Initialization.InitializationEngine.ExecuteTransition(Boolean continueTransitions)
   at EPiServer.Framework.Initialization.InitializationEngine.Initialize()
   at EPiServer.Hosting.Internal.EPiServerFrameworkHost.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__14_1(IHostedService service, CancellationToken token)
   at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)

Thanks!

/Kristoffer

#337205
Mar 14, 2025 15:17

UPDATE: The sites that works have content of the deleted type, the one that does not work has not.
I added the deleted content type again and then UAT environment also works.

Could this be a bug?

#337206
Edited, Mar 14, 2025 16:23

To improve the link status report, a new column has been added to tblContentSoftlink to reference the actual property with the broken link. I suspect that this table is not cleaned up when content (and content type) are deleted before the model synchronizer tries to remove the page type (as there is no content left it can be removed). The problem does not occur in the other environments, because you have content left, and the synchronizer will not try to delete the page type.

To investigate further, I would run the following query against the environment with the problem. It shoud return 0 rows.

SELECT top 10 * 
FROM tblContentSoftlink
WHERE fkOwnerPropertyDefinitionID NOT IN (SELECT pkId FROM tblPropertyDefinition)

If rows are returned, delete them.

#337233
Edited, Mar 17, 2025 9:49

Hi!

I've tried the query but I do not get any results, it is a strange problem.

/Kristoffer

#337242
Mar 18, 2025 13:08

Hi Kristoffer. Any updates about this? 
I am getting the same error when deploying från Integration to Preprod in DXP in a new environment, copying the blob and DB. 
Works as it should in Integration

#343172
Aug 20, 2026 10:00
Kristoffer Lindén - Aug 20, 2026 11:52
Unfortuneately not, we never solved it. Just kept the pagetype until we took backup from prod to UAT. Strange error!
Vote:

I can see how this is a bug, I will file a bug for it. Thanks for bringing it into our attention and apologies for the inconvenience.

If you need to fix it in the dev environment, this query might be sufficient 

DELETE SL
FROM dbo.tblContentSoftlink SL
INNER JOIN dbo.tblPropertyDefinition PD
    ON SL.fkOwnerPropertyDefinitionID = PD.pkID
WHERE PD.fkContentTypeID = @contentTypeID;
 
with @contentTypeID is the id of the content being deleted
#343185
Aug 20, 2026 12:04
Kristoffer Lindén - Aug 20, 2026 12:08
Thanks Quan!
Quan Mai - Aug 20, 2026 12:10
The bug is CMS-55124 but it will take a while to be fixed and released
Tomas Hensrud Gulla - Aug 20, 2026 12:35
Ah, that explains why my query came back empty. It was looking for softlinks pointing to property definitions that were already gone, but the FK error fires before those definitions get deleted, so they still exist and the reference is intact. I didn't read the original post carefully enough. But I was close, real close.
Jonas Boman - Aug 20, 2026 13:50
Using this query I got from the support I was able to identify the issue:

``SELECT *
FROM tblPropertyDefinition pd
INNER JOIN tblPropertyDefinitionType pdtype
ON pdtype.pkid = pd.fkPropertyDefinitionTypeID
WHERE EXISTS (
SELECT 1
FROM tblContentSoftlink cs
WHERE cs.fkOwnerPropertyDefinitionID = pd.pkid
);``

Then deleting by using the pkID from the faulty row:
`DELETE FROM tblContentSoftlink WHERE fkOwnerPropertyDefinitionID = mypkID;`
error This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.