HangfireIO / HangfireIO/Hangfire

Type Loading Exception in Recurring Job

Open
#2,469 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
10.1k
Forks
1.8k
Avg merge
1h 19m
Merged PRs (30d)
1

Description

I'm experiencing a TypeLoadException with a recurring job in Hangfire. The job works fine when triggered manually, but after some time, it fails in the recurring jobs tab with a type loading error.

```
System.InvalidOperationException: Recurring job can't be scheduled, see inner exception for details.
---> Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details.
---> System.TypeLoadException: Could not load type 'xMessagingAPI.Hangfire.Abstract.Jobs.ICalculateTotalSpendingsJob' from assembly 'xMessagingAPI.Hangfire, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.Reflection.RuntimeAssembly.g____PInvoke|26_0(QCallAssembly assembly, UInt16* name, Int32 throwOnError, Int32 ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
```

**Job Registration**
```c#
services.AddScoped();
RecurringJob.AddOrUpdate("calculate-total-spendings", x => x.RunAsync(), Cron.Minutely );
```
**Hangfire Registration**
```c#
services.AddHangfire((provider, configuration) =>
{
configuration.UseRedisStorage(redis, redisStrogeOptions)
.WithJobExpirationTimeout(TimeSpan.FromDays(30))
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings();
});
JobStorage.Current = new RedisStorage(redis, redisStrogeOptions);

services.AddHangfireServer(configuration =>
{
configuration.WorkerCount = 1;
configuration.Queues = new[]
{
"calculate-spendings", "sync-spendings-with-x", "set-new-balance", "sync-balances-from-x", "spend"
};
});
```

**Interface Definition**
```c#
public interface ICalculateTotalSpendingsJob
{
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Fail)]
[Queue("calculate-spendings")]
[JobDisplayName("Calculate Spendings Job")]
[DisableConcurrentExecution(60)]
public Task RunAsync();
}
```

**Implementation**
```c#
public class CalculateTotalSpendingsJob : ICalculateTotalSpendingsJob
{
private readonly IUnitOfWork _unitOfWork;
private readonly IMessageReadRepository _messageReadRepository;
private readonly IMessageWriteRepository _messageWriteRepository;
private readonly IUserService _userService;
private readonly IJobQueueService _jobQueueService;
private readonly IBalanceService _balanceService;

public CalculateTotalSpendingsJob(IUnitOfWork unitOfWork,
IMessageWriteRepository messageWriteRepository,
IMessageReadRepository messageReadRepository,
IUserService userService,
IJobQueueService jobQueueService,
IBalanceService balanceService)
{
_unitOfWork = unitOfWork;
_messageWriteRepository = messageWriteRepository;
_messageReadRepository = messageReadRepository;
_userService = userService;
_jobQueueService = jobQueueService;
_balanceService = balanceService;
}

public async Task RunAsync()
{
Console.WriteLine("OK-calculate");
return;
}
}
```

**Expected Behavior**:
- The recurring job should continue running at the specified interval (every minute)
- No type loading exceptions should occur

**Actual Behavior**:
- Job works when triggered manually
- After some time, the recurring job fails with a TypeLoadException
- The error suggests it cannot load the interface type, even though the interface exists and is properly defined

**Things I've Already Tried**:
- Verified all assembly references are correct
- Confirmed the interface and implementation are in the correct namespace
- Checked that the DLL is present in the build output directory
- Verified all dependencies are properly registered in DI
- Cleared all recurring jobs and reset the Redis database to ensure there are no stale or conflicting job definitions

**Environment**

- Hangfire Version: 1.8.15
- .NET Core Version: .NET 7.0
- Database: Redis 6.2.11
- OS: Debian GNU/Linux 11 (bullseye)
- Environment: Docker Container

Contributor guide

Open the contributing guide

Research direction

Start with the recurring job registration, Hangfire Redis storage configuration, and the reported TypeLoadException, comparing the manual and recurring execution paths. Reproduce the failure in the stated .NET 7, Hangfire 1.8.15, Redis, and Docker environment, then verify that the recurring job continues running every minute without the type-loading error.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.