{"record":{"id":"23a9cdc12e33482b","repo":"HangfireIO/Hangfire","slug":"storage-23a9cd","errorCode":null,"errorMessage":"storage","messagePattern":"storage","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/Obsolete/DashboardMiddleware.cs","lineNumber":45,"sourceCode":"{\n    internal sealed class DashboardMiddleware : OwinMiddleware\n    {\n        private readonly string _appPath;\n        private readonly int _statsPollingInterval;\n        private readonly JobStorage _storage;\n        private readonly RouteCollection _routes;\n        private readonly IEnumerable<IAuthorizationFilter> _authorizationFilters;\n\n        public DashboardMiddleware(\n            OwinMiddleware next,\n            string appPath,\n            int statsPollingInterval,\n            [NotNull] JobStorage storage,\n            [NotNull] RouteCollection routes, \n            [NotNull] IEnumerable<IAuthorizationFilter> authorizationFilters)\n            : base(next)\n        {\n            if (storage == null) throw new ArgumentNullException(nameof(storage));\n            if (routes == null) throw new ArgumentNullException(nameof(routes));\n            if (authorizationFilters == null) throw new ArgumentNullException(nameof(authorizationFilters));\n\n            _appPath = appPath;\n            _statsPollingInterval = statsPollingInterval;\n            _storage = storage;\n            _routes = routes;\n            _authorizationFilters = authorizationFilters;\n        }\n\n        public override Task Invoke(IOwinContext owinContext)\n        {\n            var dispatcher = _routes.FindDispatcher(owinContext.Request.Path.Value);\n            \n            if (dispatcher == null)\n            {\n                return Next.Invoke(owinContext);\n            }","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/Obsolete/DashboardMiddleware.cs#L27-L63","documentation":"Thrown by the obsolete DashboardMiddleware constructor (OWIN-based) when the storage parameter is null. The middleware needs a JobStorage instance to serve dashboard pages and fetch monitoring data; a null storage makes all dashboard requests fail.","triggerScenarios":"Constructing new DashboardMiddleware(next, appPath, interval, null, routes, authFilters) or an OWIN pipeline registration that passes null for the JobStorage.","commonSituations":"Using the obsolete OWIN middleware directly (instead of the recommended app.UseHangfireDashboard extension), where JobStorage.Current has not been set yet at pipeline construction time, or a misconfigured OWIN startup class.","solutions":["Use the modern app.UseHangfireDashboard() extension method instead of constructing DashboardMiddleware directly","If constructing manually, pass JobStorage.Current (ensure it is set first via UseStorage)","Ensure the OWIN startup class runs after storage configuration"],"exampleFix":"// before\napp.Use(typeof(DashboardMiddleware), next, \"/app\", 2000, null, routes, filters);\n\n// after\n// Register storage first\nGlobalConfiguration.Configuration.UseSqlServerStorage(connStr);\n// Use the extension method\napp.UseHangfireDashboard(\"/hangfire\");","handlingStrategy":"validation","validationCode":"var storage = JobStorage.Current; // ensure initialized first\nif (storage == null) throw new InvalidOperationException(\"JobStorage not configured.\");\nvar middleware = new DashboardMiddleware(next, appPath, interval, storage, routes, authFilters);","typeGuard":"storage != null && storage is JobStorage","tryCatchPattern":null,"preventionTips":["Use the modern app.UseHangfireDashboard() extension instead of constructing DashboardMiddleware directly","Ensure JobStorage.Current is set before OWIN pipeline construction","Migrate from the obsolete OWIN middleware to the current DashboardMiddleware if still on OWIN"],"tags":["null-argument","dashboard","owin","obsolete","middleware","hangfire"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}