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
- Null-check the exception before constructing ExceptionInfo: if (ex != null) info = new ExceptionInfo(ex).
- When walking InnerException, recurse only when ex.InnerException != null (the class itself already guards this in its own ctor, so user code must too).
- If your handler receives a possibly-null exception, fall back to storing a generic message instead of throwing.
- 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
- Null-check exceptions (and their InnerException) before wrapping them in ExceptionInfo.
- Enable nullable reference types so nullable exceptions are flagged at compile time.
- In exception filters, treat the exception argument as potentially null.
- Never assume InnerException is non-null when recursing.
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.