stride3d/stride · error · InvalidOperationException
A part named ' ' must be present in the ControlTemplate…
Error message
A part named '{MessageContainerPartName}' must be present in the ControlTemplate, and must be of type '{typeof(FlowDocumentScrollViewer)}'. What it means
MarkdownTextBlock.OnApplyTemplate fetches the mandatory template part 'PART_MessageContainer' and requires it to be a FlowDocumentScrollViewer. When the applied ControlTemplate is missing that part (or names it differently / uses another element type), GetTemplateChild returns null and an InvalidOperationException is thrown.
Solutions
- Add <FlowDocumentScrollViewer x:Name="PART_MessageContainer"/> to the ControlTemplate
- Verify the part name matches MessageContainerPartName exactly (case-sensitive)
- Ensure the part element is a FlowDocumentScrollViewer, not a subclass-less substitute like ContentPresenter
- Base your custom template on the library's default template for MarkdownTextBlock
Example fix
<!-- before -->
<ControlTemplate TargetType="mtb:MarkdownTextBlock">
<Border Background="Transparent"/>
</ControlTemplate>
<!-- after -->
<ControlTemplate TargetType="mtb:MarkdownTextBlock">
<Border Background="Transparent">
<FlowDocumentScrollViewer x:Name="PART_MessageContainer"/>
</Border>
</ControlTemplate> Defensive patterns
Strategy: validation
Validate before calling
// validate template parts before/after ApplyTemplate in your hosting code
var container = markdownTextBlock.Template?.FindName("PART_MessageContainer", markdownTextBlock) as FlowDocumentScrollViewer;
if (container == null) throw new InvalidOperationException("Custom MarkdownTextBlock template is missing PART_MessageContainer (FlowDocumentScrollViewer)"); Type guard
bool HasValidMarkdownTemplate(MarkdownTextBlock c) => c.Template?.FindName("PART_MessageContainer", c) is FlowDocumentScrollViewer; Try / catch
try { control.ApplyTemplate(); }
catch (InvalidOperationException ex) { log.Error(ex, "Invalid MarkdownTextBlock template; falling back to default style"); control.Style = null; } Prevention
- Never remove PART_-prefixed elements when re-templating
- Keep part names and types identical to the default template
- Test custom templates by forcing ApplyTemplate in unit tests
- Copy templates from the same library version you reference
When it happens
Trigger: Applying a custom ControlTemplate for MarkdownTextBlock that omits the part named by MessageContainerPartName, names it incorrectly, or hosts an element that is not a FlowDocumentScrollViewer.
Common situations: Re-templating the control for theming; upgrading Stride and copying an outdated template; hand-written Styles without the required part; renaming the part x:Name in XAML.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A part named ' ' must be present in the ControlTemplate…
- A part named ' ' must be present in the ControlTemplate…
- A part named 'PART_ContentHost' must be present in the…
- A part named 'PART_DecreaseButton' must be present in the…
- A part named 'PART_IncreaseButton' must be present in the…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/5d907ce27255ab1e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/MarkdownTextBlock.cs:92
static MarkdownTextBlock()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MarkdownTextBlock), new FrameworkPropertyMetadata(typeof(MarkdownTextBlock)));
}
public MarkdownTextBlock()
{
defaultMarkdown = new Lazy<XamlMarkdown>(() => new XamlMarkdown(this));
}
/// <inheritdoc/>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
messageContainer = GetTemplateChild(MessageContainerPartName) as FlowDocumentScrollViewer;
if (messageContainer == null)
throw new InvalidOperationException($"A part named '{MessageContainerPartName}' must be present in the ControlTemplate, and must be of type '{typeof(FlowDocumentScrollViewer)}'.");
ResetMessage();
}
private static void BaseUrlChanged([NotNull] DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as MarkdownTextBlock;
if (control == null) throw new ArgumentNullException(nameof(control));
if (e.NewValue != null)
{
control.GetMarkdown().BaseUrl = (string)e.NewValue;
}
control.ResetMessage();
}
private static void HyperlinkCommandChanged([NotNull] DependencyObject d, DependencyPropertyChangedEventArgs e)
{View on GitHub (pinned to 96fad776d2)