HangfireIO/Hangfire · error · ArgumentNullException

exception

Error message

exception

What it means

ExceptionInfo wraps a System.Exception (message, type name, optional inner) so it can be serialized into Hangfire job state. Its constructor rejects a null exception with ArgumentNullException(nameof(exception)) at ExceptionInfo.cs:29 because every field it populates is derived from that exception — with a null reference there is nothing to record.

Source

Thrown at src/Hangfire.Core/ExceptionInfo.cs:29

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public 
// License along with Hangfire. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Text;
using Hangfire.Annotations;
using Hangfire.Common;
using Newtonsoft.Json;

namespace Hangfire
{
    public sealed class ExceptionInfo
    {
        public ExceptionInfo([NotNull] Exception exception)
        {
            if (exception == null) throw new ArgumentNullException(nameof(exception));

            Message = exception.Message;
            Type = TypeHelper.CurrentTypeSerializer(exception.GetType());

            if (exception.InnerException != null)
            {
                InnerException = new ExceptionInfo(exception.InnerException);
            }
        }

        [JsonConstructor]
        public ExceptionInfo([NotNull] string type, [CanBeNull] string message, [CanBeNull] ExceptionInfo innerException)
        {
            Type = type ?? throw new ArgumentNullException(nameof(type));
            Message = message;
            InnerException = innerException;
        }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Null-check the exception before constructing ExceptionInfo: if (ex != null) info = new ExceptionInfo(ex).
  2. When walking InnerException, recurse only when ex.InnerException != null (the class itself already guards this in its own ctor, so user code must too).
  3. If your handler receives a possibly-null exception, fall back to storing a generic message instead of throwing.
  4. Enable nullable reference types (NullableContextOptions) so the compiler flags null-argument paths at build time.

Example fix

// before
var info = new ExceptionInfo(jobException.InnerException);
// after
var info = jobException.InnerException != null
    ? new ExceptionInfo(jobException.InnerException)
    : null;
Defensive patterns

Strategy: validation

Validate before calling

// before constructing
if (exception == null)
{
    throw new ArgumentNullException(nameof(exception));
}
var info = new ExceptionInfo(exception);

Type guard

static ExceptionInfo? SafeWrap(Exception? ex)
    => ex != null ? new ExceptionInfo(ex) : null;

Prevention

When it happens

Trigger: Calling new ExceptionInfo(null), or new ExceptionInfo(ex.InnerException) when ex.InnerException is null. In practice this surfaces inside Hangfire when persisting failed-job state, or in custom JobFilter/IStateMachine handlers / dashboard code that build an ExceptionInfo from an exception that can legitimately be null.

Common situations: Custom job filters, exception filters, or state-change handlers that pass a caught exception (or its InnerException) straight into new ExceptionInfo(...) without a null check. Also when porting code that assumed InnerException was always present.

Related errors


AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13). Data as JSON: /api/errors/421d4e4cef632649. Report an issue: GitHub.