{"record":{"id":"6a9d1ad4dc862ad6","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-create-window-of-type-typeof-twindow-n","errorCode":null,"errorMessage":"Failed to create window of type {typeof(TWindow).Name} with constructor param {typeof(TViewModel).Name}","messagePattern":"Failed to create window of type (.+?) with constructor param (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/WindowsService.cs","lineNumber":197,"sourceCode":"            await ShowModalAsync(owner, window);\n\n            return window;\n        }\n\n        public async Task<TViewModel> ShowDialogAsync<TWindow, TViewModel>(\n            Window owner,\n            Action<TViewModel>? configureViewModel = null, Action<TWindow>? configureWindow = null)\n            where TWindow : Window\n            where TViewModel : class\n        {\n            var viewModel = _serviceProvider.GetRequiredService<TViewModel>();\n            configureViewModel?.Invoke(viewModel);\n\n            // Create the window using reflection, passing in the viewModel\n            var w = Activator.CreateInstance(typeof(TWindow), viewModel);\n            if (w == null)\n            {\n                throw new InvalidOperationException($\"Failed to create window of type {typeof(TWindow).Name} with constructor param {typeof(TViewModel).Name}\");\n            }\n\n            var window = (TWindow)w;\n\n            window.WindowStartupLocation = WindowStartupLocation.CenterOwner;\n            configureWindow?.Invoke(window);\n\n            ApplyRightToLeftSettings(window);\n            UiTheme.ApplyScaleToWindow(window);\n\n            await ShowModalAsync(owner, window);\n\n            return viewModel;\n        }\n\n        /// <summary>\n        /// Shows an already-constructed window as a modal dialog with the shared foreground\n        /// handling every modal in SE needs: kept above the undocked tool windows (#11971),","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/WindowsService.cs#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: dialog ctor does not match the resolved ViewModel type\npublic sealed class FindDialog : Window\n{\n    public FindDialog(MainViewModel main) { InitializeComponent(); }\n}\nawait windowService.ShowDialogAsync<FindDialog, FindViewModel>(this);\n\n// after: ctor accepts exactly the ViewModel DI resolved\npublic sealed class FindDialog : Window\n{\n    public FindDialog(FindViewModel vm) : this()\n    {\n        DataContext = vm;\n    }\n    private FindDialog() { InitializeComponent(); }\n}\nawait windowService.ShowDialogAsync<FindDialog, FindViewModel>(this);","handlingStrategy":"validation","validationCode":"using System.Reflection;\n\nstatic bool HasViewModelCtor(Type window, Type vm) =>\n    window.GetConstructors().Any(c =>\n        c.GetParameters() is { Length: 1 } p && p[0].ParameterType == vm);\n\nif (!HasViewModelCtor(typeof(TWindow), typeof(TViewModel)))\n{\n    throw new InvalidOperationException(\n        $\"{typeof(TWindow).Name} must have a public ctor accepting {typeof(TViewModel).Name}.\");\n}\nawait windowService.ShowDialogAsync<TWindow, TViewModel>(owner, configureViewModel, configureWindow);","typeGuard":null,"tryCatchPattern":"try\n{\n    return await windowService.ShowDialogAsync<TWindow, TViewModel>(\n        owner, configureViewModel, configureWindow);\n}\ncatch (TargetInvocationException ex) when (ex.InnerException != null)\n{\n    throw ex.InnerException; // unwrap the dialog ctor's real failure\n}\ncatch (MissingMethodException ex)\n{\n    throw new InvalidOperationException(\n        $\"{typeof(TWindow).Name} has no public ctor({typeof(TViewModel).Name}).\", ex);\n}","preventionTips":["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."],"tags":["avalonia","dependency-injection","reflection","window-service","activator","modal-dialog"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}