WPFail2Ban creates fatal error by hooking into some action

Some completely unrelated plugin wouldn’t spit out its status report because it ran into a fatal error. This was due to this error:

[26-Jun-2024 13:52:03 UTC] PHP Fatal error:  Uncaught TypeError: call_user_func_array(): Argument #1 ($callback) must be a valid callback, function "com\wp_fail2ban\addons\ContactForm7\wp_fail2ban_register_plugin" not found or invalid function name in /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/class-wp-hook.php:324
Stack trace:
#0 /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#1 /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/plugin.php(517): WP_Hook->do_action()
#2 /home/bogusbogus/bogusbogus.com/public_html/www/wp-content/plugins/wp-fail2ban/init.php(238): do_action()
#3 /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/class-wp-hook.php(324): org\lecklider\charles\wordpress\wp_fail2ban\init__late()
#4 /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#5 /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/plugin.php(517): WP_Hook->do_action()
#6 /home/bogusbogus/bogusbogus.com/public_html/www/wp-settings.php(695): do_action()
#7 /home/bogusbogus/bogusbogus.com/public_html/www/wp-config.php(137): require_once('...')
#8 /home/bogusbogus/bogusbogus.com/public_html/www/wp-load.php(50): require_once('...')
#9 /home/bogusbogus/bogusbogus.com/public_html/www/wp-content/plugins/complianz-gdpr-premium/system-status.php(23): require_once('...')
#10 {main}
  thrown in /home/bogusbogus/bogusbogus.com/public_html/www/wp-includes/class-wp-hook.php on line 324

At first glance that stack trace is impossible; however, after some thought I remembered that I’d seen something like this before.

Try changing lines 132-3 in freemius.php to:

require_once __DIR__.'/functions.php';
require_once __DIR__.'/init.php';

I suspect what’s happening is that something is changing the current directory; init.php is clearly being loaded as the hook is added, but the hook itself isn’t there.