ContinueJobWith/RecurringJob.AddOrUpdate queue-string overloads silently don't control real dispatch, only set Job.Queue metadata
Calling BackgroundJob.ContinueJobWith(parentId, "myqueue", methodCall, options) or RecurringJob.AddOrUpdate(id, "myqueue", methodCall, cron) does not actually enqueue the resulting job onto myqueue. It runs on default instead. The dashboard and InvocationData.Queue still show myqueue, so this is easy to miss.
Root cause (checked against v1.8.0 and main):
ContinueJobWith(client, parentId, queue, methodCall, nextState, options)buildsnew AwaitingState(parentId, nextState ?? new EnqueuedState(), options). None of the queue-string overloads passnextState, so it falls back tonew EnqueuedState(), whose parameterless constructor hardcodes thedefaultqueue. Thequeueargument only reachesclient.Create(queue, methodCall, state), which callsJob.FromExpression(methodCall, queue)and setsJob.Queue. That's informational metadata only, not the dispatch queue.ContinuationsSupportAttribute.OnStateElectionlater reapplies that storedNextStateas is when the parent finishes. It never checksJob.Queueto correct it.- Same bug shape for
RecurringJob.AddOrUpdate(id, queue, methodCall, cron). That overload forwards to theRecurringJobOptionsoverload with a plainnew RecurringJobOptions(), never settingQueueNamefrom the givenqueue. That overload usesqueueonly forJob.FromExpression(methodCall, queue)metadata.RecurringJobManager.AddOrUpdatethen sets the recurring job's actualQueuefield fromoptions.QueueName, which stays null/default, even though the recurring job's own storage feature check (JobStorageFeatures.JobQueueProperty) confirms the storage supports per-job queues.
Related issues, though none cover these specific overloads: #1900, #1695, #2226.
Repro: create a continuation with an explicit queue, then check HangFire.JobQueue for the resulting job. It ends up under default, not the queue that was passed in.
The 1.8.0 release notes describe "first class queue support" with an example almost identical to ContinueJobWith(id, "queue", methodCall). That makes this look like a real gap between the documented behavior and the shipped code, not intentional legacy behavior. Either fix these overloads to build new EnqueuedState(queue), or update the docs to state that [Queue] is the only reliable mechanism for continuations and recurring jobs.
Source: HangfireIO/Hangfire