umbraco / Umbraco-CMS

Umbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.
https://umbraco.com
Other
4.49k stars 2.69k forks source link

after upgrading to v10 "ArgumentException: An item with the same key has already been added" error #12642

Closed vmachacek closed 1 year ago

vmachacek commented 2 years ago

Which exact Umbraco version are you using? For example: 9.0.1 - don't just write v9

10.0.0

Bug summary

After I updated Umbraco the updater did hist job and redirected to Backoffice where I saw some errors coming from bottom. And when I loaded the website it was down with 500.

Specifics

The exception with full stacktrace


ArgumentException: An item with the same key has already been added. Key: 4262

    System.Collections.Generic.Dictionary<TKey, TValue>.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
    System.Collections.Generic.Dictionary<TKey, TValue>.Add(TKey key, TValue value)
    System.Linq.Enumerable.ToDictionary<TSource, TKey>(List<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
    System.Linq.Enumerable.ToDictionary<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
    System.Linq.Enumerable.ToDictionary<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ContentTypeCommonRepository.MapHistoryCleanup(Dictionary<int, IContentTypeComposition> contentTypes)
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ContentTypeCommonRepository.GetAllTypesInternal()
    Umbraco.Extensions.AppCacheExtensions+<>c__DisplayClass0_0<T>.<GetCacheItem>b__0()
    Umbraco.Cms.Core.Cache.SafeLazy+<>c__DisplayClass1_0.<GetSafeLazy>b__0()
    Umbraco.Cms.Core.Cache.ObjectCacheAppCache.Get(string key, Func<object> factory, Nullable<TimeSpan> timeout, bool isSliding, string[] dependentFiles)
    Umbraco.Cms.Core.Cache.DeepCloneAppCache.Get(string key, Func<object> factory, Nullable<TimeSpan> timeout, bool isSliding, string[] dependentFiles)
    Umbraco.Extensions.AppCacheExtensions.GetCacheItem<T>(IAppPolicyCache provider, string cacheKey, Func<T> getCacheItem, Nullable<TimeSpan> timeout, bool isSliding, string[] dependentFiles)
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ContentTypeCommonRepository.GetAllTypes()
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ContentTypeRepository.GetAllWithFullCachePolicy()
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.ContentTypeRepositoryBase<TEntity>.PerformGetAll(int[] ids)
    Umbraco.Cms.Core.Cache.FullDataSetRepositoryCachePolicy<TEntity, TId>.GetAllCached(Func<TId[], IEnumerable<TEntity>> performGetAll)
    Umbraco.Cms.Core.Cache.FullDataSetRepositoryCachePolicy<TEntity, TId>.GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.EntityRepositoryBase<TId, TEntity>.GetMany(TId[] ids)
    Umbraco.Cms.Core.Services.ContentTypeServiceBase<TRepository, TItem>.GetAll(int[] ids)
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.LoadContentFromLocalDbLocked(bool onStartup)
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.<EnsureCaches>b__47_1()
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.LockAndLoadContent(Func<bool> action)
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.<EnsureCaches>b__47_0()
    System.Threading.LazyInitializer.EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
    System.Threading.LazyInitializer.EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.EnsureCaches()
    Umbraco.Cms.Infrastructure.PublishedCache.PublishedSnapshotService.CreatePublishedSnapshot(string previewToken)
    Umbraco.Cms.Web.Common.UmbracoContext.UmbracoContext+<>c__DisplayClass11_0.<.ctor>b__0()
    System.Lazy<T>.ViaFactory(LazyThreadSafetyMode mode)
    System.Lazy<T>.ExecutionAndPublication(LazyHelper executionAndPublication, bool useDefaultConstructor)
    System.Lazy<T>.CreateValue()
    System.Lazy<T>.get_Value()
    Umbraco.Cms.Web.Common.UmbracoContext.UmbracoContext.get_PublishedSnapshot()
    Umbraco.Cms.Web.Common.UmbracoContext.UmbracoContext.get_Content()
    Umbraco.Cms.Web.Website.Routing.UmbracoRouteValueTransformer.TransformAsync(HttpContext httpContext, RouteValueDictionary values)
    System.Threading.Tasks.ValueTask<TResult>.get_Result()
    System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
    Microsoft.AspNetCore.Mvc.Routing.DynamicControllerEndpointMatcherPolicy.ApplyAsync(HttpContext httpContext, CandidateSet candidates)
    Microsoft.AspNetCore.Routing.Matching.DfaMatcher.SelectEndpointWithPoliciesAsync(HttpContext httpContext, IEndpointSelectorPolicy[] policies, CandidateSet candidateSet)
    Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.<Invoke>g__AwaitMatch|8_1(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
    SixLabors.ImageSharp.Web.Middleware.ImageSharpMiddleware.Invoke(HttpContext httpContext, bool retry)
    StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in MiniProfilerMiddleware.cs
    Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
    Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
    Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
    Umbraco.Cms.Web.Common.Middleware.PreviewAuthenticationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
    Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
    Umbraco.Cms.Web.Common.Middleware.UmbracoRequestLoggingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
    Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
    Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

it is coming from this .ToDictionary() call - for some reason there are more than one content types of same Id ( ?? ) https://github.com/umbraco/Umbraco-CMS/blob/ce9f92909b3fe8b127afab48dd7970dcc859b716/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeCommonRepository.cs#L163

Steps to reproduce

Its a DB specific thing, probably cannot be reproduced easily

Expected result / actual result

Expected Umbraco upgades fine,

Actual Umbraco is stucked and broken

bergmania commented 2 years ago

Hi @vmachacek

Thanks for reporting.. Sounds very weird. Can you confirm the dbo.umbracoContentVersionCleanupPolicy table contains duplicate contentTypeIds ?

vmachacek commented 2 years ago

this is what is in that table

contentTypeId   keepAllVersionsNewerThanDays    keepLatestVersionPerDayForDays  preventCleanup  updated
5647    NULL    NULL    0   2022-05-31 23:27:12.123
4902    NULL    NULL    0   2022-05-31 23:24:18.357
4262    NULL    NULL    0   2022-06-10 12:58:25.280
5647    NULL    NULL    0   2022-05-31 23:27:12.123
4902    NULL    NULL    0   2022-05-31 23:24:18.357
4262    NULL    NULL    0   2022-06-10 12:58:25.280

there are 3 content types but each is there twice

vmachacek commented 2 years ago

deleting duplicates solved the issue and now app is pointing to correct db, thanks!

AndyButland commented 2 years ago

I think we should probably keep this issue open, as there's a missing primary key on this table that should have prevented the duplicate from being added in the first place. I've checked a couple of local installs and can also see it's missing.

bergmania commented 2 years ago

I agree Andy.. Seems like there is a missing primary key on contentTypeId. But I still do not understand how it ended up having duplicates.

Zeegaan commented 1 year ago

Fixed in https://github.com/umbraco/Umbraco-CMS/pull/12684 thanks for reporting 🐛