{"record":{"id":"413ac33af7f48d94","repo":"abpframework/abp","slug":"could-not-find-doworkasync-method-on-type-work","errorCode":null,"errorMessage":"Could not find 'DoWorkAsync' method on type '{workerType.FullName}'.","messagePattern":"Could not find 'DoWorkAsync' method on type '(.+?)'\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"critical","filePath":"framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQPeriodicBackgroundWorkerInvoker.cs","lineNumber":31,"sourceCode":"    private readonly Action<PeriodicBackgroundWorkerBase, PeriodicBackgroundWorkerContext>? _doWorkDelegate;\n\n    protected IBackgroundWorker Worker { get; }\n    protected IServiceProvider ServiceProvider { get; }\n\n    public AbpTickerQPeriodicBackgroundWorkerInvoker(IBackgroundWorker worker, IServiceProvider serviceProvider)\n    {\n        Worker = worker;\n        ServiceProvider = serviceProvider;\n\n        switch (worker)\n        {\n            case AsyncPeriodicBackgroundWorkerBase:\n            {\n                var workerType = worker.GetType();\n                var method = workerType.GetMethod(\"DoWorkAsync\", BindingFlags.Instance | BindingFlags.NonPublic);\n                if (method == null)\n                {\n                    throw new AbpException($\"Could not find 'DoWorkAsync' method on type '{workerType.FullName}'.\");\n                }\n\n                var instanceParam = Expression.Parameter(typeof(AsyncPeriodicBackgroundWorkerBase), \"worker\");\n                var contextParam = Expression.Parameter(typeof(PeriodicBackgroundWorkerContext), \"context\");\n                var call = Expression.Call(Expression.Convert(instanceParam, workerType), method, contextParam);\n                var lambda = Expression.Lambda<Func<AsyncPeriodicBackgroundWorkerBase, PeriodicBackgroundWorkerContext, Task>>(call, instanceParam, contextParam);\n                _doWorkAsyncDelegate = lambda.Compile();\n                break;\n            }\n            case PeriodicBackgroundWorkerBase:\n            {\n                var workerType = worker.GetType();\n                var method = workerType.GetMethod(\"DoWork\", BindingFlags.Instance | BindingFlags.NonPublic);\n                if (method == null)\n                {\n                    throw new AbpException($\"Could not find 'DoWork' method on type '{workerType.FullName}'.\");\n                }\n","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQPeriodicBackgroundWorkerInvoker.cs#L13-L49","documentation":"Thrown by AbpTickerQPeriodicBackgroundWorkerInvoker when reflecting over a worker that is an AsyncPeriodicBackgroundWorkerBase subclass, but the non-public instance method 'DoWorkAsync' cannot be found. ABP invokes this protected method via reflection+expression compilation to run the worker's periodic work. Under normal ABP versions the method always exists on the base class, so this typically signals a version mismatch or an unconventional subclass that hid/renamed it.","triggerScenarios":"Registering an AsyncPeriodicBackgroundWorkerBase-derived worker whose type, after proxy generation or inheritance, no longer exposes a non-public DoWorkAsync(PeriodicBackgroundWorkerContext) method. Most commonly caused by a framework version mismatch where the installed Volo.Abp package does not declare DoWorkAsync on the base class, or a custom override changed the method signature/accessibility.","commonSituations":"Upgrading or downgrading the ABP framework packages inconsistently (some packages at one version, others at another) where the base class API changed. A custom worker that accidentally shadows DoWorkAsync with a different signature or makes it public, breaking the BindingFlags.NonPublic lookup. A dynamic-proxy or AOP weaving that altered method visibility.","solutions":["Ensure all ABP NuGet packages are at the same version (run abp update or check all package versions) so AsyncPeriodicBackgroundWorkerBase.DoWorkAsync exists.","If you overrode DoWorkAsync, keep the signature exactly as 'protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)' and do not change its accessibility.","If the issue is proxy-related, verify the worker is registered correctly in DI and not wrapped by a custom interceptor that strips the method."],"exampleFix":"// before — method accidentally made public with a different signature\npublic class MyWorker : AsyncPeriodicBackgroundWorkerBase\n{\n    public new Task DoWorkAsync() { ... }\n}\n\n// after — correct protected override\npublic class MyWorker : AsyncPeriodicBackgroundWorkerBase\n{\n    Period = 60000;\n    protected override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)\n    {\n        return Task.CompletedTask;\n    }\n}","handlingStrategy":"validation","validationCode":"var method = worker.GetType().GetMethod(\"DoWorkAsync\", BindingFlags.Instance | BindingFlags.NonPublic);\nif (method == null)\n{\n    throw new InvalidOperationException($\"Worker {worker.GetType().FullName} is missing DoWorkAsync; check ABP package versions and method signature.\");\n}","typeGuard":"static bool HasDoWorkAsync(Type workerType) => workerType.GetMethod(\"DoWorkAsync\", BindingFlags.Instance | BindingFlags.NonPublic) != null;","tryCatchPattern":null,"preventionTips":["Keep all ABP NuGet packages at the same version.","When overriding DoWorkAsync, match the exact protected override signature.","Prefer AsyncPeriodicBackgroundWorkerBase over the synchronous base for new workers."],"tags":["tickerq","background-workers","reflection","version-mismatch","internal-api"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}