{"record":{"id":"ed74302f9042b76b","repo":"abpframework/abp","slug":"tickerq-does-not-support-dynamic-background-worker-ed7430","errorCode":null,"errorMessage":"TickerQ does not support dynamic background worker registration at runtime. Please use Hangfire or Quartz provider for dynamic background workers.","messagePattern":"TickerQ does not support dynamic background worker registration at runtime\\. Please use Hangfire or Quartz provider for dynamic background workers\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"error","filePath":"framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs","lineNumber":24,"sourceCode":"\n[Dependency(ReplaceServices = true)]\npublic class TickerQDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency\n{\n    public virtual Task AddAsync(\n        string workerName,\n        DynamicBackgroundWorkerSchedule schedule,\n        DynamicBackgroundWorkerHandler handler,\n        CancellationToken cancellationToken = default)\n    {\n        throw new AbpException(\n            \"TickerQ does not support dynamic background worker registration at runtime. \" +\n            \"TickerQ uses FrozenDictionary for function registration, which requires all functions to be registered before the application starts. \" +\n            \"Please use Hangfire or Quartz provider for dynamic background workers.\");\n    }\n\n    public virtual Task<bool> RemoveAsync(string workerName, CancellationToken cancellationToken = default)\n    {\n        throw new AbpException(\n            \"TickerQ does not support dynamic background worker registration at runtime. \" +\n            \"Please use Hangfire or Quartz provider for dynamic background workers.\");\n    }\n\n    public virtual Task<bool> UpdateScheduleAsync(\n        string workerName,\n        DynamicBackgroundWorkerSchedule schedule,\n        CancellationToken cancellationToken = default)\n    {\n        throw new AbpException(\n            \"TickerQ does not support dynamic background worker registration at runtime. \" +\n            \"Please use Hangfire or Quartz provider for dynamic background workers.\");\n    }\n\n    public virtual bool IsRegistered(string workerName)\n    {\n        // TickerQ does not support runtime registration, so there are never any registered workers.\n        return false;","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs#L6-L42","documentation":"Thrown unconditionally by TickerQDynamicBackgroundWorkerManager.RemoveAsync because TickerQ's function table is frozen at startup and cannot be modified at runtime. Removing a worker dynamically is not supported; the error message points to Hangfire or Quartz, whose dynamic managers support runtime removal.","triggerScenarios":"Calling IDynamicBackgroundWorkerManager.RemoveAsync(workerName) at runtime when the TickerQ provider is the active implementation. Occurs in code paths that tear down or reconfigure workers dynamically (e.g. disabling a feature at runtime).","commonSituations":"Application logic that removes workers based on feature flags or tenant deactivation, run under the TickerQ provider. Reusing dynamic-manager calls from a Hangfire-based codebase after switching to TickerQ.","solutions":["Use the Hangfire or Quartz provider if you need runtime worker removal.","With TickerQ, control whether a worker executes by gating its DoWork logic (feature flags, settings) rather than removing the worker itself.","Restart the application after changing the static worker registrations rather than removing at runtime."],"exampleFix":"// before — runtime removal under TickerQ (throws)\nawait dynamicManager.RemoveAsync(\"legacy-worker\", cancellationToken);\n\n// after — gate the worker body with a feature check\nprotected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext context)\n{\n    if (!await FeatureChecker.IsEnabledAsync(\"LegacyWorkerEnabled\")) return;\n    // ... actual work\n}","handlingStrategy":"try-catch","validationCode":"if (dynamicManager is Volo.Abp.BackgroundWorkers.TickerQ.TickerQDynamicBackgroundWorkerManager)\n{\n    throw new NotSupportedException(\"TickerQ does not support dynamic RemoveAsync; gate the worker logic instead.\");\n}","typeGuard":"static bool SupportsDynamicRemoval(IDynamicBackgroundWorkerManager mgr) => mgr is not Volo.Abp.BackgroundWorkers.TickerQ.TickerQDynamicBackgroundWorkerManager;","tryCatchPattern":"try { await dynamicManager.RemoveAsync(name, ct); }\ncatch (AbpException ex) when (ex.Message.Contains(\"does not support dynamic background worker registration\"))\n{\n    logger.LogWarning(ex, \"Cannot remove worker at runtime under TickerQ; gate the worker body with a flag instead.\");\n}","preventionTips":["Use feature flags or settings to disable a worker's logic at runtime instead of removing the worker under TickerQ.","Switch to Hangfire/Quartz if runtime removal is a product requirement.","Document which dynamic operations each provider supports in your project's onboarding docs."],"tags":["tickerq","dynamic-workers","provider-limitation","unsupported-operation"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}