abpframework/abp · error · AbpException
TickerQ does not support dynamic background worker registrat
Error message
TickerQ does not support dynamic background worker registration at runtime. TickerQ uses FrozenDictionary for function registration, which requires all functions to be registered before the application starts. Please use Hangfire or Quartz provider for dynamic background workers.
What it means
Thrown unconditionally by TickerQDynamicBackgroundWorkerManager.AddAsync because TickerQ uses a FrozenDictionary for function registration that is frozen at application startup. TickerQ cannot register background worker functions after the host has started, so the dynamic AddAsync contract is intentionally unsupported. The error directs you to Hangfire or Quartz, which do support runtime registration.
Source
Thrown at framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs:16
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.BackgroundWorkers.TickerQ;
[Dependency(ReplaceServices = true)]
public class TickerQDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency
{
public virtual Task AddAsync(
string workerName,
DynamicBackgroundWorkerSchedule schedule,
DynamicBackgroundWorkerHandler handler,
CancellationToken cancellationToken = default)
{
throw new AbpException(
"TickerQ does not support dynamic background worker registration at runtime. " +
"TickerQ uses FrozenDictionary for function registration, which requires all functions to be registered before the application starts. " +
"Please use Hangfire or Quartz provider for dynamic background workers.");
}
public virtual Task<bool> RemoveAsync(string workerName, CancellationToken cancellationToken = default)
{
throw new AbpException(
"TickerQ does not support dynamic background worker registration at runtime. " +
"Please use Hangfire or Quartz provider for dynamic background workers.");
}
public virtual Task<bool> UpdateScheduleAsync(
string workerName,
DynamicBackgroundWorkerSchedule schedule,
CancellationToken cancellationToken = default)
{
throw new AbpException(View on GitHub (pinned to 7ed43b1931)
Solutions
- Switch to the Hangfire (Volo.Abp.BackgroundWorkers.Hangfire) or Quartz (Volo.Abp.BackgroundWorkers.Quartz) provider, whose dynamic managers support runtime AddAsync.
- If you must keep TickerQ, register all workers statically at startup (via AddBackgroundWorkerAsync or module configuration) instead of dynamically at runtime.
- Before calling AddAsync, guard with IsRegistered or check the provider type to avoid the unsupported path.
Example fix
// before — dynamic registration with TickerQ (throws)
public class MyService
{
public MyService(IDynamicBackgroundWorkerManager dynamicManager)
{
dynamicManager.AddAsync("on-demand-worker", schedule, handler).Wait();
}
}
// after — use Hangfire provider instead (in your module DependsOn)
[DependsOn(typeof(AbpBackgroundWorkersHangfireModule))]
// remove or do not depend on AbpBackgroundWorkersTickerQModule
public class MyAppModule : AbpModule { } Defensive patterns
Strategy: try-catch
Validate before calling
if (dynamicManager is Volo.Abp.BackgroundWorkers.TickerQ.TickerQDynamicBackgroundWorkerManager)
{
throw new NotSupportedException("TickerQ does not support dynamic AddAsync; use Hangfire or Quartz.");
} Type guard
static bool SupportsDynamicRegistration(IDynamicBackgroundWorkerManager mgr) => mgr is not Volo.Abp.BackgroundWorkers.TickerQ.TickerQDynamicBackgroundWorkerManager;
Try / catch
try { await dynamicManager.AddAsync(name, schedule, handler, ct); }
catch (AbpException ex) when (ex.Message.Contains("does not support dynamic background worker registration"))
{
logger.LogError(ex, "Active provider does not support dynamic worker registration. Switch to Hangfire or Quartz.");
} Prevention
- If runtime worker registration is a requirement, depend on AbpBackgroundWorkersHangfireModule or AbpBackgroundWorkersQuartzModule instead of TickerQ.
- Detect the active provider at startup and fail fast with a clear message if dynamic features are needed but unsupported.
- Register all TickerQ workers statically at startup.
When it happens
Trigger: Resolving IDynamicBackgroundWorkerManager at runtime (e.g. in an application service or hosted service) and calling AddAsync while the TickerQ background workers provider is the active implementation. This happens when the project references Volo.Abp.BackgroundWorkers.TickerQ and no Hangfire/Quartz provider overrides the default.
Common situations: Migrating from the in-memory dynamic worker manager to TickerQ without realizing TickerQ is static-registration only. Designing a feature that creates workers on demand (e.g. per-tenant scheduling) and then switching the provider to TickerQ for production reliability.
Related errors
- TickerQ does not support dynamic background worker registrat
- The default in-memory background worker manager does not sup
- Background job execution is disabled. This method should not
- Cannot convert period: {period} to cron expression.
- Both 'Period' and 'CronExpression' are not set for {worker.G
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/10f886fe965a997a.
Report an issue: GitHub.