{"record":{"id":"33345af82aef951b","repo":"HangfireIO/Hangfire","slug":"type","errorCode":null,"errorMessage":"type","messagePattern":"type","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/ExceptionInfo.cs","lineNumber":43,"sourceCode":"    public sealed class ExceptionInfo\n    {\n        public ExceptionInfo([NotNull] Exception exception)\n        {\n            if (exception == null) throw new ArgumentNullException(nameof(exception));\n\n            Message = exception.Message;\n            Type = TypeHelper.CurrentTypeSerializer(exception.GetType());\n\n            if (exception.InnerException != null)\n            {\n                InnerException = new ExceptionInfo(exception.InnerException);\n            }\n        }\n\n        [JsonConstructor]\n        public ExceptionInfo([NotNull] string type, [CanBeNull] string message, [CanBeNull] ExceptionInfo innerException)\n        {\n            Type = type ?? throw new ArgumentNullException(nameof(type));\n            Message = message;\n            InnerException = innerException;\n        }\n\n        [NotNull]\n        [JsonProperty(\"e\")]\n        public string Type { get; }\n\n        [CanBeNull]\n        [JsonProperty(\"m\", NullValueHandling = NullValueHandling.Ignore)]\n        public string Message { get; }\n\n        [CanBeNull]\n        [JsonProperty(\"i\", NullValueHandling = NullValueHandling.Ignore)]\n        public ExceptionInfo InnerException { get; }\n\n        public override string ToString()\n        {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/ExceptionInfo.cs#L25-L61","documentation":"ExceptionInfo is deserialized by Newtonsoft.Json via its [JsonConstructor], which requires the type (JSON property \"e\") to be non-null — otherwise it throws ArgumentNullException(nameof(type)) at ExceptionInfo.cs:43. The type string is the only mandatory field; Message (\"m\") and InnerException (\"i\") are optional and ignored when null.","triggerScenarios":"Deserializing JSON into ExceptionInfo where the \"e\" property is absent, explicitly null, or empty. Happens when reading corrupt or partial job-state JSON from storage, or when JSON produced by an older/newer Hangfire version omits \"e\".","commonSituations":"Corrupted persisted job state in the storage backend, a schema/serialization mismatch after a Hangfire upgrade or after toggling compatibility level, or a custom serialization settings override that drops the \"e\" token.","solutions":["Inspect the stored JSON for the failing job/state and confirm the \"e\" property exists and is non-null.","Align Hangfire versions across all producers/consumers (worker, server, dashboard) so the serialized shape matches.","Set CompatibilityLevel to the same value everywhere via SetDataCompatibilityLevel so serialization rules agree.","Delete or expire the corrupt state and let Hangfire re-serialize it; enable job expiration to flush stale records.","If you provide custom JsonSerializerSettings, ensure they do not strip or rename the \"e\" property."],"exampleFix":"// before\nvar info = JsonConvert.DeserializeObject<ExceptionInfo>(corruptJson);\n// after\nvar token = JObject.Parse(json)[\"e\"];\nvar info = token != null && token.Type != JTokenType.Null\n    ? JsonConvert.DeserializeObject<ExceptionInfo>(json)\n    : null;","handlingStrategy":"validation","validationCode":"// before deserializing into ExceptionInfo\nvar obj = JObject.Parse(json);\nvar typeToken = obj[\"e\"];\nif (typeToken == null || typeToken.Type == JTokenType.Null)\n{\n    throw new InvalidDataException(\"ExceptionInfo JSON is missing required 'e' (type) field.\");\n}\nvar info = obj.ToObject<ExceptionInfo>();","typeGuard":"static bool HasExceptionType(string json)\n{\n    var t = JObject.Parse(json)[\"e\"];\n    return t != null && t.Type != JTokenType.Null;\n}","tryCatchPattern":"try\n{\n    var info = JsonConvert.DeserializeObject<ExceptionInfo>(json);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"type\")\n{\n    // corrupt/partial state: log and skip\n    _log.Warn(\"Skipping ExceptionInfo with missing 'e' field.\");\n}","preventionTips":["Keep all Hangfire nodes on the same version and compatibility level so serialized shapes agree.","Do not strip or rename the 'e' property with custom JsonSerializerSettings.","Periodically expire/clean job state so corrupt records age out.","Validate stored JSON shapes in integration tests after upgrades."],"tags":["csharp","hangfire","argument-null","json","serialization","deserialization"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}