Henrik Fransas
Apr 15, 2014
  3610
(1 votes)

The danger of renaming contentypes and how to fix it

Last week we experienced a hard problem to debug, but easy to solve. It was hard to debug because it didn’t happen in development or test environment, only in production environment after a deploy and the error message we got was not helping at all.

What was happening was that after the deploy to production the site crashed and gave us this message:
”Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.”
With the stacktrace:

“[SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1767866
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5352418
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +244
   System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1691
   System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows) +322
   System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more) +230
   System.Data.SqlClient.SqlDataReader.TryNextResult(Boolean& more) +189
   System.Data.SqlClient.SqlDataReader.NextResult() +28
   System.Data.ProviderBase.DataReaderContainer.NextResult() +19
   System.Data.Common.DataAdapter.FillNextResult(DataReaderContainer dataReader) +51
   System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue) +233
   System.Data.Common.DataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) +421
   System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +173
   System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) +316
   System.Data.Common.DbDataAdapter.Fill(DataSet dataSet) +88
   EPiServer.DataAccess.<>c__DisplayClassa.<DeleteDB>b__9() +240
   EPiServer.Data.Providers.<>c__DisplayClass7`1.<ExecuteTransaction>b__6() +200
   EPiServer.Data.Providers.SqlDeadlockRetryPolicy.Execute(Boolean isInTransaction, Func`1 method) +716
   EPiServer.Data.Providers.SqlDatabaseHandler.ExecuteTransaction(Func`1 action) +302
   EPiServer.DataAccess.ContentTypeDB.DeleteDB(Int32 pageTypeID) +171
   EPiServer.DataAccess.ContentTypeDB.Delete(ContentType contentType) +278
   EPiServer.DataAbstraction.DefaultContentTypeRepository.Delete(ContentType contentType) +174
   EPiServer.DataAbstraction.BlockTypeRepository.Delete(BlockType blockType) +40
   EPiServer.DataAbstraction.RuntimeModel.ContentTypeSynchronizer`2.Delete(T contentType) +104
   EPiServer.DataAbstraction.RuntimeModel.ContentTypeModelRegister`2.CommitTypes(Boolean deleteUnusedTypes) +365
   EPiServer.DataAbstraction.RuntimeModel.ContentTypeModelScanner`3.Sync(Boolean commitChanges) +131
   EPiServer.Initialization.ModelSyncInitialization.Initialize(InitializationEngine context) +580
   EPiServer.Framework.Initialization.<>c__DisplayClass5.<Initialize>b__4() +56
   EPiServer.Framework.Initialization.ModuleNode.Execute(Action a, String key) +73
   EPiServer.Framework.Initialization.ModuleNode.Initialize(InitializationEngine context) +141
   EPiServer.Framework.Initialization.InitializationEngine.InitializeModules() +445
   EPiServer.Framework.Initialization.InitializationEngine.Initialize(HostType hostType) +256
   EPiServer.Framework.Initialization.InitializationModule.Initialize(HostType hostType) +344
   EPiServer.Framework.Initialization.InitializationModule.FrameworkInitialization(HostType hostType) +78
   EPiServer.Global..ctor() +83
   SITENAME.Web.Global..ctor() +29
   ASP.global_asax..ctor() in c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\8fc7b944\c53070aa\App_global.asax.0.cs:0”

In itself the message or stack trace was not helping us much at all more than telling us that something happen when EPiServer was initializing the site. Luckily for us, we had only made a couple of changes between the last deployment and this (the great thing of agile development!) so looking what those check in was about and the error message said we could narrow it down to a rename of a content type.
Why didn’t it happen in development or test? That is a good question and nothing I have the answer to, if you do, please tell me in a comment. I checked the database and there were no content created for this content type.
To solve the problem, we just added a migration to the project that looked like this:

    public class MigrateEducationListBLock : MigrationStep
    {
        public override void AddChanges()
        {
            ContentType("LocationEducationFavoritesListBlock")
                .UsedToBeNamed("EducationListBlock");
        }
    }
Apr 15, 2014

Comments

Apr 15, 2014 05:33 PM

Did you specify GUIDs on your content types before renaming them?

valdis
valdis Apr 15, 2014 06:32 PM

Interesting. We haven't come across this error in rename cases..

Henrik Fransas
Henrik Fransas Apr 15, 2014 08:49 PM

Daniel: The first version was created without a GUID specified and when we did the rename we specified the GUID but with a new one, thinking that it would just delete the old contenttype. The first version was a "to early checkin..." that had gone all the way to production.

Valdis: It was the first time for us also, and bare in mind that it did not show in development or test, only in production so it is very strange.

Apr 16, 2014 10:08 AM

Ah ok! Yeah, specifying PageTypes without GUID and then renaming them will definitely get you into trouble. Been there, done that :)

Apr 16, 2014 10:11 AM

Be careful about changing namespace as well if you don't have GUIDs specified for your pagetype btw. DO use GUIDs...always...

Henrik Fransas
Henrik Fransas Apr 16, 2014 10:36 AM

Thanks Daniel, yes, thankfully we will learn from our mistake :)

Please login to comment.
Latest blogs
Preview multiple Visitor Groups directly while browsing your Optimizely site

Visitor groups are great - it's an easy way to add personalization towards market segments to your site. But it does come with it's own set of...

Allan Thraen | Sep 26, 2022 | Syndicated blog

The Report Center is finally back in Optimizely CMS 12

With Episerver.CMS.UI 12.12.0 the Report Center is finally re-introduced in the core product.

Tomas Hensrud Gulla | Sep 26, 2022 | Syndicated blog

Dynamic Route in ASP.NET Core When MapDynamicControllerRoute Does Not Work

Background Creating one of the add-on for Optimizely I had to deal with challenge to register dynamically route for the API controller. Dynamic rou...

valdis | Sep 25, 2022 | Syndicated blog

404 Error on Static Assets Within an Optimizely plugin

Background With the move to CMS 12 and .NET 5/6, developers are now able to build Plugins and Extensions using Razor Class Libraries (RCL).  These...

Mark Stott | Sep 23, 2022

How to bypass the content creation view in Optimizely

Something that has come up a couple of times in the last few year is feedback from content editors about the editing view that comes up when creati...

Ynze | Sep 23, 2022 | Syndicated blog

Welcome to Optimizely World's New Tech Video Portal

Optimizely, leader in the digital experience realm, has become a wealth of world class SaaS products including Web Experimentation, Full Stack, B2B...

The Developer Marketing Team of Optimizely | Sep 22, 2022