SubtitleEdit/subtitleedit · error · InvalidOperationException
Failed to create window of type {typeof(TWindow).Name} with
Error message
Failed to create window of type {typeof(TWindow).Name} with constructor param {typeof(TViewModel).Name} What it means
Thrown by WindowService.ShowDialogAsync<TWindow,TViewModel> when Activator.CreateInstance(typeof(TWindow), viewModel) returns null. Same mechanism as 424/425 but on the modal-dialog path: the ViewModel is resolved from DI, configureViewModel runs, then the window is built via Activator. For reference-type Windows, Activator throws (MissingMethodException / TargetInvocationException) instead of returning null, so the guard is defensive and the live failures come through as those exceptions.
Source
Thrown at src/ui/Logic/WindowsService.cs:197
await ShowModalAsync(owner, window);
return window;
}
public async Task<TViewModel> ShowDialogAsync<TWindow, TViewModel>(
Window owner,
Action<TViewModel>? configureViewModel = null, Action<TWindow>? configureWindow = null)
where TWindow : Window
where TViewModel : class
{
var viewModel = _serviceProvider.GetRequiredService<TViewModel>();
configureViewModel?.Invoke(viewModel);
// Create the window using reflection, passing in the viewModel
var w = Activator.CreateInstance(typeof(TWindow), viewModel);
if (w == null)
{
throw new InvalidOperationException($"Failed to create window of type {typeof(TWindow).Name} with constructor param {typeof(TViewModel).Name}");
}
var window = (TWindow)w;
window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
configureWindow?.Invoke(window);
ApplyRightToLeftSettings(window);
UiTheme.ApplyScaleToWindow(window);
await ShowModalAsync(owner, window);
return viewModel;
}
/// <summary>
/// Shows an already-constructed window as a modal dialog with the shared foreground
/// handling every modal in SE needs: kept above the undocked tool windows (#11971),View on GitHub (pinned to 17a9f07487)
Solutions
- Confirm the dialog window TWindow has a public constructor whose single parameter is the registered TViewModel.
- Catch and inspect the TargetInvocationException.InnerException from the Activator call to find the actual missing DI registration or null argument.
- Register TViewModel and every service the dialog constructor depends on in the service collection.
- Verify the call-site generic order: <TWindow, TViewModel> (window first, viewmodel second).
- If the dialog needs extra construction data, pass it through configureViewModel/configureWindow on an already-built instance rather than extra Activator constructor arguments.
Example fix
// before: dialog ctor does not match the resolved ViewModel type
public sealed class FindDialog : Window
{
public FindDialog(MainViewModel main) { InitializeComponent(); }
}
await windowService.ShowDialogAsync<FindDialog, FindViewModel>(this);
// after: ctor accepts exactly the ViewModel DI resolved
public sealed class FindDialog : Window
{
public FindDialog(FindViewModel vm) : this()
{
DataContext = vm;
}
private FindDialog() { InitializeComponent(); }
}
await windowService.ShowDialogAsync<FindDialog, FindViewModel>(this); Defensive patterns
Strategy: validation
Validate before calling
using System.Reflection;
static bool HasViewModelCtor(Type window, Type vm) =>
window.GetConstructors().Any(c =>
c.GetParameters() is { Length: 1 } p && p[0].ParameterType == vm);
if (!HasViewModelCtor(typeof(TWindow), typeof(TViewModel)))
{
throw new InvalidOperationException(
$"{typeof(TWindow).Name} must have a public ctor accepting {typeof(TViewModel).Name}.");
}
await windowService.ShowDialogAsync<TWindow, TViewModel>(owner, configureViewModel, configureWindow); Try / catch
try
{
return await windowService.ShowDialogAsync<TWindow, TViewModel>(
owner, configureViewModel, configureWindow);
}
catch (TargetInvocationException ex) when (ex.InnerException != null)
{
throw ex.InnerException; // unwrap the dialog ctor's real failure
}
catch (MissingMethodException ex)
{
throw new InvalidOperationException(
$"{typeof(TWindow).Name} has no public ctor({typeof(TViewModel).Name}).", ex);
} Prevention
- Every dialog opened via ShowDialogAsync<TWindow,TViewModel> must have a public ctor(TViewModel).
- Register the ViewModel and all transitive services before the dialog is shown.
- Pass extra construction data through configureViewModel/configureWindow, not through additional Activator ctor args.
- Keep generic argument order <Window, ViewModel> consistent at every call site.
When it happens
Trigger: ShowDialogAsync<TWindow,TViewModel>(owner, configureViewModel, configureWindow) is called for a modal dialog. DI resolves TViewModel and configureViewModel(configureViewModel) runs; then Activator tries TWindow's constructor(TViewModel). It fails when there is no public constructor taking a single TViewModel, or when that constructor throws (a DI service it needs is unregistered or null). The literal null-check throw is the unreachable-for-reference-types tail.
Common situations: A dialog window was created without a public constructor accepting its ViewModel; the registered TViewModel type does not match the constructor parameter type; the dialog constructor calls GetRequiredService on something not registered, throwing inside the ctor; generic arguments at the call site are reversed; a refactor moved or renamed the ViewModel out of sync with the dialog ctor.
Related errors
- Failed to create window of type {typeof(T).Name} with constr
- Color '{colorName}' not found in SKColors.
- Invalid hex string.
- MpvPlayer is not initialized
- VlcPlayer is not initialized
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/6a9d1ad4dc862ad6.
Report an issue: GitHub.