{"record":{"id":"f931ce7ec0ee007d","repo":"OrchardCMS/OrchardCore","slug":"failed-to-retrieve-the-current-endpoint-route-builder","errorCode":null,"errorMessage":"Failed to retrieve the current endpoint route builder.","messagePattern":"Failed to retrieve the current endpoint route builder\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore/Modules/Extensions/ShellPipelineExtensions.cs","lineNumber":84,"sourceCode":"    }\n\n    /// <summary>\n    /// Configures the tenant pipeline.\n    /// </summary>\n    private static async ValueTask ConfigurePipelineAsync(ApplicationBuilder builder)\n    {\n        // 'IStartup' instances are ordered by module dependencies with a 'ConfigureOrder' of 0 by default.\n        // 'OrderBy' performs a stable sort, so the order is preserved among equal 'ConfigureOrder' values.\n        var startups = builder.ApplicationServices.GetServices<IStartup>().OrderBy(s => s.ConfigureOrder);\n\n        // Should be done first.\n        builder.UseRouting();\n\n        // Try to retrieve the current 'IEndpointRouteBuilder'.\n        if (!builder.Properties.TryGetValue(EndpointRouteBuilder, out var obj) ||\n            obj is not IEndpointRouteBuilder routes)\n        {\n            throw new InvalidOperationException(\"Failed to retrieve the current endpoint route builder.\");\n        }\n\n        // Routes can be then configured outside 'UseEndpoints()'.\n        var services = ShellScope.Services;\n        foreach (var startup in startups)\n        {\n            if (startup is IAsyncStartup asyncStartup)\n            {\n                await asyncStartup.ConfigureAsync(builder, routes, services);\n            }\n\n            startup.Configure(builder, routes, services);\n        }\n\n        // Knowing that routes are already configured.\n        builder.UseEndpoints(routes => { });\n    }\n}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore/Modules/Extensions/ShellPipelineExtensions.cs#L66-L102","documentation":"When composing a shell's request pipeline, Orchard Core calls UseRouting and then reads the IEndpointRouteBuilder stored by the routing middleware in builder.Properties (key 'EndpointRouteBuilder') so module routes can be configured outside UseEndpoints. If the property is absent or holds a different object, endpoint routing never ran or was replaced, and this InvalidOperationException is thrown.","triggerScenarios":"Calling ConfigurePipelineAsync (via UseOrchardCore/BuildPipelineInternalAsync) on an IApplicationBuilder where UseRouting() was not invoked before, or where a custom middleware/branch replaced the EndpointRouteBuilder entry, or where EndpointRoutingMiddleware was disabled (UseRouting called after this code or globally disabled).","commonSituations":"Custom Startup/patch code removes or reorders UseRouting; a third-party middleware framework clears builder.Properties; running with a minimal host that skips endpoint routing; misordered pipeline configuration during shell rebuild.","solutions":["Ensure UseRouting() is called on the application builder before the shell pipeline is composed.","Do not remove or overwrite the 'EndpointRouteBuilder' entry in builder.Properties.","Check custom IStartup filter ordering so endpoint routing middleware runs before module route configuration.","If using custom pipeline branching, compose the shell on the main pipeline where routing is active."],"exampleFix":"// before\napp.UseStaticFiles();\napp.UseOrchardCore(); // shell pipeline expects routing state\n\n// after\napp.UseStaticFiles();\napp.UseRouting();\napp.UseOrchardCore();","handlingStrategy":"try-catch","validationCode":"// Before composing the shell pipeline:\nif (!builder.Properties.TryGetValue(\"EndpointRouteBuilder\", out var obj) || obj is not IEndpointRouteBuilder)\n    throw new InvalidOperationException(\"Call app.UseRouting() before UseOrchardCore().\");","typeGuard":"bool HasEndpointRouteBuilder(IApplicationBuilder builder) =>\n    builder.Properties.TryGetValue(\"__EndpointRouteBuilder\", out var obj) && obj is IEndpointRouteBuilder;","tryCatchPattern":"try { await builder.ConfigurePipelineAsync(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"endpoint route builder\"))\n{\n    _logger.LogCritical(ex, \"Endpoint routing middleware missing; check UseRouting placement\");\n    throw;\n}","preventionTips":["Always place app.UseRouting() before app.UseOrchardCore() in Program.cs/Startup.","Never delete or overwrite entries in builder.Properties.","Keep UseRouting at top-level pipeline, not inside conditional branches.","Smoke-test shell pipeline startup after introducing routing-related middleware."],"tags":["routing","pipeline","endpoints","aspnetcore"],"backgroundTag":"invalid-state-transition","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}