Search code examples
c#asp.net-corejobshangfirerecurring

The 'Job' field has a null or empty value in Hangfire


In Startup.cs I tried to enqueue recurring job like this:

RecurringJob.AddOrUpdate(() => Console.WriteLine("test"), Cron.Daily);

but received the error:

enter image description here

Please help to figure out what I'm doing wrong.

My configuration:

    //HangFire
    services.AddHangfire(configuration => configuration
      .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
      .UseSimpleAssemblyNameTypeSerializer()
      .UseRecommendedSerializerSettings()
      .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"),
          new SqlServerStorageOptions
          {
              CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
              SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
              QueuePollInterval = TimeSpan.Zero,
              UseRecommendedIsolationLevel = true,
              DisableGlobalLocks = true,
          }
      ));

P.S. although 'fire and forget' jobs works.


Solution

  • Hangfire's source indicates that this exception (and message) is thrown when the expression !recurringJob.ContainsKey("Job") || String.IsNullOrWhiteSpace(recurringJob["Job"]) is true.

    try
    {
        if (!recurringJob.ContainsKey("Job") || String.IsNullOrWhiteSpace(recurringJob["Job"]))
        {
            throw new InvalidOperationException("The 'Job' field has a null or empty value");
        }
    
        Job = InvocationData.DeserializePayload(recurringJob["Job"]).DeserializeJob();
    }
    catch (Exception ex)
    {
        _errors.Add(ex);
    }
    

    The recurringJob Dictionary gets set by the method GetAllEntriesFromHash:

    public override Dictionary<string, string> GetAllEntriesFromHash(string key)
    {
        if (key == null) throw new ArgumentNullException(nameof(key));
    
        return _storage.UseConnection(_dedicatedConnection, connection =>
        {
            var result = connection.Query<SqlHash>(
                $"select Field, Value from [{_storage.SchemaName}].Hash with (forceseek, readcommittedlock) where [Key] = @key",
                new { key },
                commandTimeout: _storage.CommandTimeout)
                .ToDictionary(x => x.Field, x => x.Value);
    
            return result.Count != 0 ? result : null;
        });
    }
    

    So what is probably happening is the GetAllEntriesFromHash method is returning null, or a Dictionary that doesn't contain the key Job (or it's null/whitespace). But, in a thread, a Hangfire Contributor commented:

    That's not even a problem, just ignore those exceptions or tell Visual Studio to not to break on them. Hangfire handles a lot of exceptions, and may generate tons of OperationCanceledException during shutdown that tells all the background processes that shutdown was requested.

    Thus, it seems like this error can be ignored.