Summary
Tutor LMS 4.0.5 causes a fatal error on every WordPress request when get_role( tutor()->instructor_role ) returns null.
The issue occurs in Tutor::update_instructor_capability(), which calls $role->has_cap() without checking whether the role exists.
Environment
- Tutor LMS: 4.0.5
- WordPress: 7.0.4
- PHP: 8.3.33
- Existing installation where Tutor LMS had not yet been configured or used
Observed conditions
- The
tutor_instructor role was not present.
tutor_removed_edit_other_items_permission was false or absent, so the new capability migration ran.
- Loading any WordPress endpoint triggered the fatal error, including the frontend,
wp-login.php, and wp-admin/.
Error
Uncaught Error: Call to a member function has_cap() on null
in wp-content/plugins/tutor/classes/Tutor.php:1452
Stack trace:
#0 wp-includes/class-wp-hook.php: TUTOR\Tutor->update_instructor_capability()
#1 wp-includes/plugin.php: WP_Hook->do_action()
#2 wp-settings.php: do_action()
#3 wp-config.php
#4 wp-load.php
#5 wp-login.php
The site returned HTTP 500 on all tested WordPress endpoints until Tutor LMS was deactivated through WordPress Recovery Mode.
Root cause
Tutor LMS 4.0.5 added this logic:
$role = get_role( tutor()->instructor_role );
foreach ( $cap_to_be_removed as $cap ) {
if ( $role->has_cap( $cap ) ) {
$role->remove_cap( $cap );
}
}
WordPress documents that get_role() returns WP_Role|null; therefore, the returned value must be checked before calling has_cap():
https://developer.wordpress.org/reference/functions/get_role/
The relevant Tutor LMS commits appear to be:
- Initial capability change: 95665d2
- Refactor into
update_instructor_capability(): 8473b13
Expected behavior
Tutor LMS should not cause a fatal error when the instructor role is missing.
The capability migration should either:
- safely recreate/repair the expected instructor role; or
- return without marking the migration complete until a valid
WP_Role object exists.
For example:
$role = get_role( tutor()->instructor_role );
if ( ! $role instanceof \WP_Role ) {
return;
}
The option tutor_removed_edit_other_items_permission should only be updated after the role exists and the intended capabilities have been processed.
Current workaround
Tutor LMS 4.0.5 remains deactivated. No plugin files or course data were deleted.
Please confirm whether the plugin should automatically recreate the missing tutor_instructor role and include a defensive fix in the next release.
Summary
Tutor LMS 4.0.5 causes a fatal error on every WordPress request when
get_role( tutor()->instructor_role )returnsnull.The issue occurs in
Tutor::update_instructor_capability(), which calls$role->has_cap()without checking whether the role exists.Environment
Observed conditions
tutor_instructorrole was not present.tutor_removed_edit_other_items_permissionwas false or absent, so the new capability migration ran.wp-login.php, andwp-admin/.Error
The site returned HTTP 500 on all tested WordPress endpoints until Tutor LMS was deactivated through WordPress Recovery Mode.
Root cause
Tutor LMS 4.0.5 added this logic:
WordPress documents that
get_role()returnsWP_Role|null; therefore, the returned value must be checked before callinghas_cap():https://developer.wordpress.org/reference/functions/get_role/
The relevant Tutor LMS commits appear to be:
update_instructor_capability(): 8473b13Expected behavior
Tutor LMS should not cause a fatal error when the instructor role is missing.
The capability migration should either:
WP_Roleobject exists.For example:
The option
tutor_removed_edit_other_items_permissionshould only be updated after the role exists and the intended capabilities have been processed.Current workaround
Tutor LMS 4.0.5 remains deactivated. No plugin files or course data were deleted.
Please confirm whether the plugin should automatically recreate the missing
tutor_instructorrole and include a defensive fix in the next release.