{"record":{"id":"56420f1ee4df8b58","repo":"abpframework/abp","slug":"there-is-no-active-uow-56420f","errorCode":null,"errorMessage":"There is no active UOW.","messagePattern":"There is no active UOW\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.Caching/Volo/Abp/Caching/Hybrid/AbpHybridCache.cs","lineNumber":426,"sourceCode":"                .NotifyAsync(new ExceptionNotificationContext(ex, LogLevel.Warning));\n        }\n    }\n\n    protected virtual bool ShouldConsiderUow(bool considerUow)\n    {\n        return considerUow && UnitOfWorkManager.Current != null;\n    }\n\n    protected virtual string GetUnitOfWorkCacheKey()\n    {\n        return UowCacheName + CacheName;\n    }\n\n    protected virtual Dictionary<TCacheKey, UnitOfWorkCacheItem<TCacheItem>> GetUnitOfWorkCache()\n    {\n        if (UnitOfWorkManager.Current == null)\n        {\n            throw new AbpException($\"There is no active UOW.\");\n        }\n\n        return UnitOfWorkManager.Current.GetOrAddItem(GetUnitOfWorkCacheKey(),\n            key => new Dictionary<TCacheKey, UnitOfWorkCacheItem<TCacheItem>>());\n    }\n\n    private readonly ConcurrentDictionary<Type, object> _serializersCache = new();\n\n    protected virtual IHybridCacheSerializer<TCacheItem> ResolveSerializer()\n    {\n        if (_serializersCache.TryGetValue(typeof(TCacheItem), out var serializer))\n        {\n            return serializer.As<IHybridCacheSerializer<TCacheItem>>();\n        }\n\n        serializer = ServiceProvider.GetService<IHybridCacheSerializer<TCacheItem>>();\n        if (serializer is null)\n        {","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/Hybrid/AbpHybridCache.cs#L408-L444","documentation":"Same guard as in DistributedCache, duplicated in the Hybrid cache implementation (AbpHybridCache). GetUnitOfWorkCache throws when IUnitOfWorkManager.Current is null because the hybrid cache also tracks per-UOW changes so reads/writes stay consistent with the in-flight transaction before flushing to the distributed cache.","triggerScenarios":"AbpHybridCache invokes GetUnitOfWorkCache while UnitOfWorkManager.Current is null. Reachable when a caller uses the hybrid cache with UOW consideration enabled outside of any active unit of work, or via an internal flush path that assumes a UOW exists.","commonSituations":"Using IHybridCache from a background job/hosted service without beginning a UOW; calling cache methods that default to considerUow=true outside a request; migrating from IDistributedCache to hybrid cache without auditing UOW usage in non-request code paths.","solutions":["Begin a unit of work before interacting with the hybrid cache: await using var uow = UnitOfWorkManager.Begin(requiresNew: true); ... await uow.CompleteAsync();","Disable UOW consideration for the call if transactional consistency is not required.","Ensure background services explicitly create a UOW scope (they do not inherit one like HTTP request handlers do).","Register the cache-using service as transient/scoped so it resolves within the correct UOW-aware DI scope."],"exampleFix":"// before: hybrid cache used in a hosted service with no UOW\npublic async Task RunAsync()\n{\n    await _hybridCache.SetAsync(key, value); // throws: no active UOW\n}\n\n// after: open a unit of work inside the background worker\npublic async Task RunAsync()\n{\n    await using (var uow = _unitOfWorkManager.Begin(requiresNew: true))\n    {\n        await _hybridCache.SetAsync(key, value);\n        await uow.CompleteAsync();\n    }\n}","handlingStrategy":"validation","validationCode":"// Gate hybrid cache UOW participation on an active UOW.\nif (unitOfWorkManager.Current == null)\n{\n    // Either open a UOW or operate without UOW consideration.\n    await using var uow = unitOfWorkManager.Begin(requiresNew: true);\n    await hybridCache.SetAsync(key, value);\n    await uow.CompleteAsync();\n}\nelse\n{\n    await hybridCache.SetAsync(key, value);\n}","typeGuard":"public static bool HasActiveUnitOfWork(IUnitOfWorkManager uowManager) =>\n    uowManager.Current is not null;","tryCatchPattern":"try\n{\n    await hybridCache.SetAsync(key, value);\n}\ncatch (AbpException ex) when (ex.Message.Contains(\"no active UOW\", StringComparison.Ordinal))\n{\n    logger.LogWarning(ex, \"Hybrid cache call outside UOW; opening one and retrying.\");\n    await using var uow = unitOfWorkManager.Begin(requiresNew: true);\n    await hybridCache.SetAsync(key, value);\n    await uow.CompleteAsync();\n}","preventionTips":["Audit hosted services and background jobs to ensure they begin a UOW before using the hybrid cache.","Prefer request-scoped services for cache interactions so the UOW is inherited.","Document which cache operations require a UOW.","Add a startup filter that fails fast if the hybrid cache is used without a UOW provider configured."],"tags":["caching","unit-of-work","hybrid","dependency-injection"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}