Describe the bug
Dynamicweb.Host.Core.Middleware.InitializersMiddleware.Invoke runs RunInitializers() on every registered IPipeline in rank order inside one try { ... } catch (Exception) { } with an empty catch, then sets _wasInvoked = true. If one initializer throws, every pipeline after it in rank order is skipped, nothing is logged, and the middleware never runs them again until the application restarts.
ClassicFrontendPipeline has Rank = int.MaxValue, so it always runs last. Its RunInitializers calls ItemManager.Initialize(), UrlPageTreeHelper.Instance.BuildPageUrlTree() and UrlIndex.BuildIndexes(). Any add-in pipeline with a lower rank whose initializer throws once (for example a database timeout during start-up) therefore leaves the whole frontend without item types and URL index for the lifetime of the process:
- every friendly URL returns 404,
Default.aspx?ID=<page> renders an empty shell,
- item-based paragraph templates throw
NullReferenceException on Model.Item,
with no log entry that names the cause. A restart fixes it, which makes the outage easy to blame on the last content change.
To Reproduce
- Install an add-in that registers an
IPipeline with Rank below int.MaxValue whose RunInitializers() throws (in the case observed, an add-in start-up SQL statement hit Execution Timeout Expired).
- Restart the application and request any page.
Observed
On a DW 10.29.4 solution, one application start hit a timeout in an add-in initializer (rank 0):
2026-09-22 08:03:08.7835: INSERT INTO McpConfigurationCredential (...) SELECT ... FROM McpConfiguration c WHERE ... NOT EXISTS (...).
Microsoft.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired.
at Dynamicweb.Data.Database.ExecuteNonQuery(IDbCommand command)
From that start until a manual recycle about 90 minutes later: every friendly URL in the webshop areas returned 404, Default.aspx?ID=<page> rendered an empty shell, and each request to / logged 17 NullReferenceExceptions in Swift paragraph templates whose only dereference is Model.Item. The item-manager start-up log line that appears at every other start (two or more xml-files which contains items with same system name, written during ItemManager.Initialize) was missing for that start only. Nothing logged the skipped initialization.
Source (decompiled, identical in Dynamicweb.Host.Core 10.28.11 and 10.29.4):
UpdateManager.ExecuteUpdates();
await context.RequestServices.GetRequiredService<CloudHostingManager>().HandleRingChange();
try
{
foreach (IPipeline pipeline in _pipelines) // ordered by Rank
{
pipeline.RunInitializers();
}
}
catch (Exception)
{
}
_wasInvoked = true;
Dynamicweb.Frontend.Classic.ClassicFrontendPipeline: Rank { get; } = int.MaxValue; RunInitializers() calls ItemManager.Initialize(); UrlPageTreeHelper.Instance.BuildPageUrlTree(); UrlIndex.BuildIndexes();.
Expected behavior
- Each pipeline's
RunInitializers() runs in its own try/catch, so one failing add-in does not prevent the platform's own initializers from running.
- The exception is logged with the pipeline type name.
- Optionally, a failed initializer is retried on a later request instead of being marked done.
Environment
- Dynamicweb 10.29.4 (observed), same code in 10.28.11 (.NET 10 hosting)
- Add-in: an MCP add-in build whose initializer ran unguarded inside
RunInitializers (the current 0.6.0-BETA build guards and logs its own start-up, so it no longer triggers this; the platform behaviour is unchanged)
Describe the bug
Dynamicweb.Host.Core.Middleware.InitializersMiddleware.InvokerunsRunInitializers()on every registeredIPipelinein rank order inside onetry { ... } catch (Exception) { }with an empty catch, then sets_wasInvoked = true. If one initializer throws, every pipeline after it in rank order is skipped, nothing is logged, and the middleware never runs them again until the application restarts.ClassicFrontendPipelinehasRank = int.MaxValue, so it always runs last. ItsRunInitializerscallsItemManager.Initialize(),UrlPageTreeHelper.Instance.BuildPageUrlTree()andUrlIndex.BuildIndexes(). Any add-in pipeline with a lower rank whose initializer throws once (for example a database timeout during start-up) therefore leaves the whole frontend without item types and URL index for the lifetime of the process:Default.aspx?ID=<page>renders an empty shell,NullReferenceExceptiononModel.Item,with no log entry that names the cause. A restart fixes it, which makes the outage easy to blame on the last content change.
To Reproduce
IPipelinewithRankbelowint.MaxValuewhoseRunInitializers()throws (in the case observed, an add-in start-up SQL statement hitExecution Timeout Expired).Observed
On a DW 10.29.4 solution, one application start hit a timeout in an add-in initializer (rank 0):
From that start until a manual recycle about 90 minutes later: every friendly URL in the webshop areas returned 404,
Default.aspx?ID=<page>rendered an empty shell, and each request to/logged 17NullReferenceExceptions in Swift paragraph templates whose only dereference isModel.Item. The item-manager start-up log line that appears at every other start (two or more xml-files which contains items with same system name, written duringItemManager.Initialize) was missing for that start only. Nothing logged the skipped initialization.Source (decompiled, identical in Dynamicweb.Host.Core 10.28.11 and 10.29.4):
Dynamicweb.Frontend.Classic.ClassicFrontendPipeline:Rank { get; } = int.MaxValue;RunInitializers()callsItemManager.Initialize(); UrlPageTreeHelper.Instance.BuildPageUrlTree(); UrlIndex.BuildIndexes();.Expected behavior
RunInitializers()runs in its own try/catch, so one failing add-in does not prevent the platform's own initializers from running.Environment
RunInitializers(the current 0.6.0-BETA build guards and logs its own start-up, so it no longer triggers this; the platform behaviour is unchanged)