abpframework/abp · error · AbpException
There is no active UOW.
Error message
There is no active UOW.
What it means
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.
Source
Thrown at framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs:1565
.Select(key => new KeyValuePair<TCacheKey, TCacheItem?>(key, default))
.ToArray();
}
protected virtual bool ShouldConsiderUow(bool considerUow)
{
return considerUow && UnitOfWorkManager.Current != null;
}
protected virtual string GetUnitOfWorkCacheKey()
{
return UowCacheName + CacheName;
}
protected virtual Dictionary<TCacheKey, UnitOfWorkCacheItem<TCacheItem>> GetUnitOfWorkCache()
{
if (UnitOfWorkManager.Current == null)
{
throw new AbpException($"There is no active UOW.");
}
return UnitOfWorkManager.Current.GetOrAddItem(GetUnitOfWorkCacheKey(),
key => new Dictionary<TCacheKey, UnitOfWorkCacheItem<TCacheItem>>());
}
}
View on GitHub (pinned to 7ed43b1931)
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.
Example fix
// before: cache call outside a unit of work with considerUow true
await _cache.SetAsync(key, value, considerUow: true); // throws: no active UOW
// after: open a unit of work first
await using (var uow = _unitOfWorkManager.Begin(requiresNew: true))
{
await _cache.SetAsync(key, value, considerUow: true);
await uow.CompleteAsync();
}
// or explicitly skip UOW participation
await _cache.SetAsync(key, value, considerUow: false); Defensive patterns
Strategy: validation
Validate before calling
// Only pass considerUow:true when a UOW is active. var considerUow = unitOfWorkManager.Current != null; await cache.SetAsync(key, value, considerUow: considerUow);
Type guard
public static bool HasActiveUnitOfWork(IUnitOfWorkManager uowManager) =>
uowManager.Current is not null; Try / catch
try
{
await cache.SetAsync(key, value, considerUow: true);
}
catch (AbpException ex) when (ex.Message.Contains("no active UOW", StringComparison.Ordinal))
{
// Either begin a UOW or repeat the call with considerUow: false.
logger.LogWarning(ex, "Cache write attempted without a UOW; retrying without UOW participation.");
await cache.SetAsync(key, value, considerUow: false);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- There is no active UOW.
- No BLOB Storage provider was registered! At least one provid
- Could not find the BLOB Storage provider with the type ({con
- No IHybridCacheSerializer configured for type '{typeof(TCach
- Could not find singleton service: {typeof(T).AssemblyQualifi
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/2a121cf99afc0d99.
Report an issue: GitHub.