{"record":{"id":"2a121cf99afc0d99","repo":"abpframework/abp","slug":"there-is-no-active-uow","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/DistributedCache.cs","lineNumber":1565,"sourceCode":"            .Select(key => new KeyValuePair<TCacheKey, TCacheItem?>(key, default))\n            .ToArray();\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","sourceCodeStart":1547,"sourceCodeEnd":1572,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs#L1547-L1572","documentation":"Thrown by DistributedCache<TCacheKey,TCacheItem>.GetUnitOfWorkCache() when IUnitOfWorkManager.Current is null. This method accumulates cache writes inside the current unit of work so they are committed/rolled back atomically. Calling it outside a UOW scope is a contract violation; the public cache API is expected to gate on ShouldConsiderUow first.","triggerScenarios":"A code path invokes a cache write/read with considerUow=true (or directly calls GetUnitOfWorkCache) while no unit of work is active. Typically this is an internal path bug or a caller that set considerUow=true without guaranteeing a UOW, e.g., a background service or static initializer that did not open a UOW via IUnitOfWorkManager.Begin.","commonSituations":"Calling IDistributedCache methods with considerUow:true from a hosted service, IHostedService, or a constructor where no UOW has been begun; calling from an event handler that runs outside the request/UOW scope; a custom subclass overriding cache methods and invoking GetUnitOfWorkCache unconditionally.","solutions":["Wrap the cache usage in a UOW: await using (var uow = UnitOfWorkManager.Begin(requiresNew: true)) { ... await cache.SetAsync(...); await uow.CompleteAsync(); }","Pass considerUow: false when you intentionally operate outside a UOW.","Ensure the calling service is registered correctly and runs within a UOW-enabled scope (e.g., inside a UnitOfWork attribute on an app service).","If overriding DistributedCache, only call GetUnitOfWorkCache when ShouldConsiderUow returns true."],"exampleFix":"// before: cache call outside a unit of work with considerUow true\nawait _cache.SetAsync(key, value, considerUow: true); // throws: no active UOW\n\n// after: open a unit of work first\nawait using (var uow = _unitOfWorkManager.Begin(requiresNew: true))\n{\n    await _cache.SetAsync(key, value, considerUow: true);\n    await uow.CompleteAsync();\n}\n\n// or explicitly skip UOW participation\nawait _cache.SetAsync(key, value, considerUow: false);","handlingStrategy":"validation","validationCode":"// Only pass considerUow:true when a UOW is active.\nvar considerUow = unitOfWorkManager.Current != null;\nawait cache.SetAsync(key, value, considerUow: considerUow);","typeGuard":"public static bool HasActiveUnitOfWork(IUnitOfWorkManager uowManager) =>\n    uowManager.Current is not null;","tryCatchPattern":"try\n{\n    await cache.SetAsync(key, value, considerUow: true);\n}\ncatch (AbpException ex) when (ex.Message.Contains(\"no active UOW\", StringComparison.Ordinal))\n{\n    // Either begin a UOW or repeat the call with considerUow: false.\n    logger.LogWarning(ex, \"Cache write attempted without a UOW; retrying without UOW participation.\");\n    await cache.SetAsync(key, value, considerUow: false);\n}","preventionTips":["In background services, always begin a UOW before cache operations that need transactional consistency.","Default to considerUow:false when running outside request scope unless you explicitly opened a UOW.","Do not override GetUnitOfWorkCache without gating on ShouldConsiderUow.","Add integration tests that exercise cache writes from non-request code paths."],"tags":["caching","unit-of-work","dependency-injection"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}