{"record":{"id":"19ed02308c20ba42","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-create-window-of-type-typeof-t-name-w","errorCode":null,"errorMessage":"Failed to create window of type {typeof(T).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":121,"sourceCode":"\n            window.Show();\n            window.Focus();\n\n            return window;\n        }\n\n        /// <inheritdoc />\n        public TViewModel ShowWindow<T, TViewModel>(Window owner, Action<T, TViewModel>? configureViewModel = null)\n            where T : Window\n            where TViewModel : class\n        {\n            var viewModel = _serviceProvider.GetRequiredService<TViewModel>();\n\n            // Create the window using reflection, passing in the viewModel\n            var w = Activator.CreateInstance(typeof(T), viewModel);\n            if (w == null)\n            {\n                throw new InvalidOperationException($\"Failed to create window of type {typeof(T).Name} with constructor param {typeof(TViewModel).Name}\");\n            }\n\n            var window = (T)w;\n            configureViewModel?.Invoke(window, viewModel);\n\n            window.WindowStartupLocation = WindowStartupLocation.CenterOwner;\n\n            // Must run before Show() - see the note in ShowWindow<T>. (#12665)\n            ApplyRightToLeftSettings(window);\n            UiTheme.ApplyScaleToWindow(window);\n\n            window.Show(owner);\n            window.Focus();\n\n            return viewModel;\n        }\n\n        /// <inheritdoc />","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/WindowsService.cs#L103-L139","documentation":"Thrown by WindowService.ShowWindow<T,TViewModel> when Activator.CreateInstance(typeof(T), viewModel) returns null after resolving the ViewModel from DI. For a reference-type Window this null return is effectively unreachable — Activator throws (MissingMethodException if no public ctor(TViewModel) exists, TargetInvocationException wrapping any exception the ctor raised) rather than returning null. So in practice you hit this guard only via the exception paths, but the guard's message names the intended diagnosis: the window could not be built from (TViewModel).","triggerScenarios":"ShowWindow<T,TViewModel>(owner, configureViewModel) is called. The DI container resolves TViewModel (throws InvalidOperationException if unregistered — a different error). Then Activator.CreateInstance tries to invoke T's constructor taking a single TViewModel. Real failures surface as exceptions: MissingMethodException when T has no public constructor(TViewModel); TargetInvocationException when the constructor itself throws (e.g. its own DI dependency is missing). The literal null-check throw is the defensive tail.","commonSituations":"A new Window was added without a public constructor accepting its ViewModel; the constructor signature takes a different parameter type than the registered TViewModel; the Window's constructor calls a DI service that throws (service not registered, null argument); the Window and ViewModel types were swapped at the call site; refactor renamed/moved the ViewModel so the ctor param type no longer matches.","solutions":["Confirm window type T has a single public constructor whose parameter type is exactly TViewModel (the type registered in DI).","Run the app under the debugger and inspect the inner exception of the TargetInvocationException thrown by Activator — that names the real missing service or null argument.","Register TViewModel (and every service the window's constructor needs) in the service collection before calling ShowWindow.","Verify the generic arguments at the call site are ordered <WindowType, ViewModelType> and not accidentally swapped.","If a window legitimately needs extra ctor arguments, switch to the parameterless CreateWindow<T> path or add an overload rather than relying on the single-param Activator call."],"exampleFix":"// before: window lacks the expected single-ViewModel constructor\npublic sealed class SettingsWindow : Window\n{\n    public SettingsWindow() { InitializeComponent(); } // no ViewModel param\n}\nvar vm = windowService.ShowWindow<SettingsWindow, SettingsViewModel>(this);\n\n// after: ctor takes exactly the ViewModel that DI resolved\npublic sealed class SettingsWindow : Window\n{\n    public SettingsWindow(SettingsViewModel vm) : this()\n    {\n        DataContext = vm;\n    }\n    private SettingsWindow() { InitializeComponent(); }\n}\nvar vm = windowService.ShowWindow<SettingsWindow, SettingsViewModel>(this);","handlingStrategy":"validation","validationCode":"// Verify the window has the constructor the Activator call needs before showing it.\nusing System.Reflection;\n\nstatic bool HasViewModelCtor(Type window, Type vm)\n{\n    return window.GetConstructors().Any(c =>\n        c.GetParameters() is { Length: 1 } p && p[0].ParameterType == vm);\n}\n\nif (!HasViewModelCtor(typeof(T), typeof(TViewModel)))\n{\n    throw new InvalidOperationException(\n        $\"{typeof(T).Name} must have a public ctor accepting {typeof(TViewModel).Name}.\");\n}\nreturn windowService.ShowWindow<T, TViewModel>(owner, configureViewModel);","typeGuard":null,"tryCatchPattern":"// The real failure arrives as an exception from Activator.CreateInstance,\n// not the null guard — catch and unwrap the inner cause for the user.\ntry\n{\n    return windowService.ShowWindow<T, TViewModel>(owner, configureViewModel);\n}\ncatch (TargetInvocationException ex) when (ex.InnerException != null)\n{\n    throw ex.InnerException; // surface the missing-service/null-arg from the window ctor\n}\ncatch (MissingMethodException ex)\n{\n    throw new InvalidOperationException(\n        $\"{typeof(T).Name} has no public ctor({typeof(TViewModel).Name}).\", ex);\n}","preventionTips":["Give every DI-backed Window a single public constructor taking its ViewModel — that is the contract ShowWindow<T,TViewModel> assumes.","Register both the ViewModel and every service the window constructor needs before any ShowWindow call.","Keep a unit test that reflects over each Window used with this API and asserts the ctor(ViewModel) exists.","Double-check call-site generic order: <WindowType, ViewModelType>."],"tags":["avalonia","dependency-injection","reflection","window-service","activator"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}