This one appears to be caused not by the sequence of events listed, but simply a bug.
When you are on the registration form, and you enter an invalid password (as determined by the ACP password level, high/med/low) the form will show a caution symbol next to the password fields to show they are invalid. Of course the member registering can ignore that and hit submit.
Once they submit with a password that will fail, it will be caught by the registerMember() function and the error(s) set in $reg_errors->hasErrors() registerMember() will return false instead of a memberID.
The current logic does not check for reg_errors and instead trys to log the agreement (and optional privacy policy) to the log_agreement_accept which needs the member id, which is false and you get the above error. I think we can simply move those two logging actions after the error checking.
$lang = !empty($modSettings['userLanguage']) ? $modSettings['userLanguage'] : 'english';
$agreement = new Agreement($lang);
$agreement->accept($memberID, $user_info['ip'], empty($modSettings['agreementRevision']) ? strftime('%Y-%m-%d', forum_time(false)) : $modSettings['agreementRevision']);
if (!empty($modSettings['requirePrivacypolicy']))
{
$policy = new \PrivacyPolicy($lang);
$policy->accept($memberID, $user_info['ip'], empty($modSettings['privacypolicyRevision']) ? strftime('%Y-%m-%d', forum_time(false)) : $modSettings['privacypolicyRevision']);
}
// If there are "important" errors and you are not an admin: log the first error
// Otherwise grab all of them and don't log anything
if ($reg_errors->hasErrors(1) && !$user_info['is_admin'])
{
foreach ($reg_errors->prepareErrors(1) as $error)
throw new Elk_Exception($error, 'general');
}
// Was there actually an error of some kind dear boy?
if ($reg_errors->hasErrors())
{
$this->_req->post->step = 2;
$this->action_register();
return false;
}
// If there are "important" errors and you are not an admin: log the first error
// Otherwise grab all of them and don't log anything
if ($reg_errors->hasErrors(1) && !$user_info['is_admin'])
{
foreach ($reg_errors->prepareErrors(1) as $error)
throw new Elk_Exception($error, 'general');
}
// Was there actually an error of some kind dear boy?
if ($reg_errors->hasErrors())
{
$this->_req->post->step = 2;
$this->action_register();
return false;
}
$lang = !empty($modSettings['userLanguage']) ? $modSettings['userLanguage'] : 'english';
$agreement = new Agreement($lang);
$agreement->accept($memberID, $user_info['ip'], empty($modSettings['agreementRevision']) ? strftime('%Y-%m-%d', forum_time(false)) : $modSettings['agreementRevision']);
if (!empty($modSettings['requirePrivacypolicy']))
{
$policy = new \PrivacyPolicy($lang);
$policy->accept($memberID, $user_info['ip'], empty($modSettings['privacypolicyRevision']) ? strftime('%Y-%m-%d', forum_time(false)) : $modSettings['privacypolicyRevision']);
}
And tracked https://github.com/elkarte/Elkarte/issues/3296