Heya
,
I’m having an issue with primary_action
in frappe.msgprint()
not properly passing arguments to a whitelisted method.
The Issue
When using primary_action
to call frappe.core.doctype.user.user.reset_password
, I get:
TypeError: reset_password() missing 1 required positional argument: 'user'
Code
Important context note: this code is part of a server script.
frappe.msgprint(
msg="Email already exists. Click button to receive password reset email.",
title="Existing User",
indicator="orange",
primary_action={
'label': 'Send Reset Email',
'server_action': 'frappe.core.doctype.user.user.reset_password',
'args': {'user': doc.email},
},
raise_exception=True
)
What I’ve Verified
- Network payload shows correct data:
{"user":"test@example.com"}
- Method signature:
def reset_password(user: str) -> str:
- Method is whitelisted:
@frappe.whitelist(allow_guest=True, methods=["POST"])
Attempted Solutions
Tried different argument formats:
'args': {'user': doc.email}

'args': doc.email

'user': doc.email

Has anyone encountered this issue with primary_action
argument passing form a frappe.msgprint() call? Is there a known workaround or correct syntax for passing arguments to whitelisted methods via primary_action
?
Any insights would be greatly appreciated!
Cheers,
Antoine.
1 Like
Hello,
What is your version of apps?
I have copied your code and tested it is working.
Reset password request for user: testpassword@example.com
@frappe.whitelist(allow_guest=True, methods=["POST"])
@rate_limit(limit=get_password_reset_limit, seconds=60 * 60)
def reset_password(user: str) -> str:
print(f"Reset password request for user: {user}")
...
Hey @Abdeali,
Thank you for your reply.
I am seeing this error on a site that runs Frappe Framework: v15.69.0
Here is an example where I’m running the code snippet straight into the system console
|
You’re able to run without issues? Including pressing the button to trigger the primary action?
Antoine.
Hey,
You are right running this code in system console is not working.
@frappe.whitelist(allow_guest=True, methods=["POST"])
@rate_limit(limit=get_password_reset_limit, seconds=60 * 60)
def reset_password( *args, **kwargs) -> str:
print("reset_password", args, kwargs)
...
result is:
reset_password () {'args': '{"user":"test@example.com"}', 'cmd': 'frappe.core.doctype.user.user.reset_password'}
Maybe frappe bug.
If you have custom app. Then why don’t you add this to your custom app.
Hey @Abdeali,
That is a good idea but I found a workaround.
Instead of sending a reset password email when the user clicks on the button I am redirecting them directly to the reset page like so:
reset_link = frappe.utils.get_url() + "/login#forgot"
frappe.msgprint(
msg=f"""This email already belongs to a user .<br><br>
<a href='{reset_link}' target='_blank' class='btn btn-primary btn-sm'>
Reset my password
</a><br><br>
<small>Or copy this link: <code>{reset_link}</code></small>""",
title="Existing User",
indicator="orange",
raise_exception=True,
)
Thanks for looking into this and I agree that it looks like a bug!
Antoine.
2 Likes