After much trial and error, I finally found a solution that worked for me.
First, I found the following role capabilities to be required to upload files for custom user roles:
$capabilites = array(
'read' => true,
'upload_files' => true,
'edit_published_pages' => true,
'edit_others_pages' => true
);
I'm not sure why these are specifically required, but the error kept occurring without them.
Second, I had to update a function I was using to prevent non-admin users from accessing the Dashboard:
function redirect_nonadmin_fromdash(){
if($_SERVER['PHP_SELF'] == '/wp-admin/async-upload.php'){
/* allow users to upload files */
return true;
} else if(get_user_role() != 'administrator'){
/* custom function get_user_role() checks user role,
requires administrator, else redirects */
wp_safe_redirect(home_url());
exit;
}
}
add_action( 'login_form_login', 'redirect_nonadmin_fromdash' );
add_action( 'admin_init', 'redirect_nonadmin_fromdash', 1 );
Previously, I was checking for the media-upload.php, but the new media uploader uses async-upload.php.
So, essentially, this allows non-admin users to use the new media uploader from the front-end without allowing them access to the Dashboard.
It also restricts their access to the Media Library, which was also important to me.