OrchardCMS/OrchardCore · error · InvalidOperationException
' . ' must not be empty. At least one ' ' is required to…
Error message
'{0}.{1}' must not be empty. At least one '{2}' is required to locate a view for rendering. What it means
RazorShapeTemplateViewEngine renders shape templates through Razor views using the first IViewEngine registered in MvcViewOptions.ViewEngines. If the ViewEngines collection is empty there is no engine to locate the view, so the method throws InvalidOperationException. This indicates the MVC view-engine configuration is broken or was cleared.
Solutions
- Ensure the application/tenant calls the Orchard Core MVC conventions (AddOrchardCore().AddMvc()) so RazorViewEngine is registered
- Remove any code that clears MvcViewOptions.ViewEngines
- Register at least one IViewEngine via services.Configure<MvcViewOptions>(o => o.ViewEngines.Add(...))
- Check per-tenant Startup modules so the tenant enabling the shape rendering has the MVC feature enabled
Example fix
// before services.Configure<MvcViewOptions>(o => o.ViewEngines.Clear()); // after services.AddOrchardCore().AddMvc(); // keeps default RazorViewEngine registered
Defensive patterns
Strategy: validation
Validate before calling
var viewEngines = serviceProvider.GetRequiredService<IOptions<MvcViewOptions>>().Value.ViewEngines;
if (viewEngines.Count == 0) { throw new InvalidOperationException("No IViewEngine registered; enable Orchard Core MVC conventions."); } Try / catch
try { await shapeRender; } catch (InvalidOperationException e) when (e.Message.Contains("must not be empty")) { /* fix startup config */ } Prevention
- Never clear MvcViewOptions.ViewEngines in custom startup
- Enable the MVC feature/conventions for every tenant that renders shapes
- Add integration coverage that renders at least one Razor shape template
When it happens
Trigger: MvcViewOptions.ViewEngines has no registered view engines at the time a Razor-based shape template is rendered — e.g. custom startup code removed the default RazorViewEngine, or MVC view services were not configured for the tenant.
Common situations: Custom module startup replacing/clearing view engine registrations; misconfigured tenant pipeline that skips AddViews/AddMvc conventions; a stripped-down host missing OrchardCore.Mvc conventions.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- A feature is missing a mandatory 'Id' property in the Module
- File path must be a non-empty string.
- Top level JSON element must be an object. Instead
- Can't use the numeric key
- Can't use the non numeric key
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/cb1b5be1224f2658.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs:81
var viewData = new ViewDataDictionary(viewContext.ViewData);
viewData.TemplateInfo.HtmlFieldPrefix = displayContext.HtmlFieldPrefix;
var htmlHelper = MakeHtmlHelper(viewContext, viewData);
return htmlHelper.PartialAsync(viewName, displayContext.Value);
}
else
{
return RenderRazorViewAsync(viewName, displayContext);
}
}
private async Task<IHtmlContent> RenderRazorViewAsync(string viewName, DisplayContext displayContext)
{
var viewEngines = _options.Value.ViewEngines;
if (viewEngines.Count == 0)
{
throw new InvalidOperationException(string.Format("'{0}.{1}' must not be empty. At least one '{2}' is required to locate a view for rendering.",
typeof(MvcViewOptions).FullName,
nameof(MvcViewOptions.ViewEngines),
typeof(IViewEngine).FullName));
}
var viewEngine = viewEngines[0];
var result = await RenderViewToStringAsync(viewName, displayContext.Value, viewEngine);
return new HtmlString(result);
}
public async Task<string> RenderViewToStringAsync(string viewName, object model, IViewEngine viewEngine)
{
var actionContext = await _httpContextAccessor.HttpContext.GetActionContextAsync();
var view = FindView(actionContext, viewName, viewEngine);
using var output = new ZStringWriter();View on GitHub (pinned to 4306c0717f)