BCUninstaller/Bulk-Crap-Uninstaller · error · InvalidOperationException

Hotkey handler called when parent form was null

Error message

Hotkey handler called when parent form was null

What it means

Thrown inside GlobalHotkeys.KeyDown_Handler, the KeyPreview event handler attached to the parent form. If _parentForm is null when a key event arrives it raises InvalidOperationException. Because ParentForm is set to null during Dispose(true), this can fire if a queued key event is delivered after disposal or if the handler was subscribed but ParentForm was never assigned.

Source

Thrown at source/KlocTools/Subsystems/GlobalHotkeys.cs:132

                ParentForm = ContainerControl.ParentForm;
            else
                throw new InvalidOperationException("Could not find the parent form");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                ParentForm = null;
                Clear();
            }
            base.Dispose(disposing);
        }

        private void KeyDown_Handler(object sender, KeyEventArgs e)
        {
            if (_parentForm == null)
                throw new InvalidOperationException("Hotkey handler called when parent form was null");

            foreach (var hotkey in _registeredHotkeys)
            {
                if (hotkey.Alt == e.Alt && hotkey.Ctrl == e.Control && hotkey.Shift == e.Shift &&
                    hotkey.KeyCode == e.KeyCode)
                {
                    if (hotkey.EventHandler == null || !hotkey.IsEnabled ||
                        (StopWhenFormIsDisabled && !ParentForm.Enabled))
                        continue;

                    hotkey.EventHandler(_parentForm, EventArgs.Empty);

                    // Stops default windows "wtfding" sound and prevents event bubbling
                    if (SuppressKeyPresses)
                        e.SuppressKeyPress = true;

                    // Do not process any more hotkeys
                    return;

View on GitHub (pinned to 608321de98)

Solutions

  1. Dispose the GlobalHotkeys component before the form closes so the handler detaches (the setter removes the KeyDown subscription).
  2. Guard consumers by ensuring ParentForm is non-null for the lifetime of the subscription.
  3. If you control a fork, downgrade the throw to an early return when _parentForm == null.

Example fix

// before: form closes, queued KeyDown fires after ParentForm set to null -> throws

// after: dispose the component first so the handler unsubscribes
protected override void OnFormClosing(FormClosingEventArgs e)
{
    globalHotkeys1.Dispose();
    base.OnFormClosing(e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (globalHotkeys1.ParentForm == null) return; // no form, skip synthesised events

Try / catch

try { /* code raising KeyDown synthetically */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("parent form was null"))
{ /* component disposed mid-event; ignore */ }

Prevention

When it happens

Trigger: A KeyDown event raised on a form whose GlobalHotkeys._parentForm is null — typically a keystroke delivered during/after Dispose (race with ParentForm=null), or manual subscription without ever setting ParentForm.

Common situations: Form closing while a key is still in the input queue, re-parenting logic that nulls ParentForm then re-raises focus, or unit-test harnesses that synthesise KeyEvents without a form.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/2098c7af87655d80. Report an issue: GitHub.