Frappe permission type is always None


I am trying to set up custom permissions using the has_permission hook, but the permission_type passed by frappe is always None, so I cannot determine the correct permission. Here is my code:

has_permission = {
    "Sales Invoice": "tcs.permissions.sales_invoice_has_permission",

def sales_invoice_has_permission(doc, user=None, permission_type=None):
    frappe.msgprint(f"permission_type: {permission_type}", "Permission Check")

When I open any Sales Invoice, this is the debug message:

Here is a stacktrace of the method call (I generated this by temporarily placing a error in my method on purpose):

Traceback (most recent call last):
  File "apps/frappe/frappe/", line 95, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/", line 55, in handle
    return frappe.handler.handle()
  File "apps/frappe/frappe/", line 47, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/", line 85, in execute_cmd
    return, **frappe.form_dict)
  File "apps/frappe/frappe/", line 1628, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/desk/form/", line 39, in getdoc
    if not doc.has_permission("read"):
  File "apps/frappe/frappe/model/", line 211, in has_permission
    return frappe.permissions.has_permission(self.doctype, permtype, self)
  File "apps/frappe/frappe/", line 49, in inner
    result = func(*args, **kwargs)
  File "apps/frappe/frappe/", line 113, in has_permission
    perm = get_doc_permissions(doc, user=user, ptype=ptype).get(ptype)
  File "apps/frappe/frappe/", line 182, in get_doc_permissions
    if has_controller_permissions(doc, ptype, user=user) is False:
  File "apps/frappe/frappe/", line 383, in has_controller_permissions
    controller_permission =, doc=doc, ptype=ptype, user=user)
  File "apps/frappe/frappe/", line 1628, in call
    return fn(*args, **newargs)

I am trying to prevent certain users on certains documents from printing or emailing, but without the permission_type (or ptype), this is not possible.

ERPNext: v14.58.1 (version-14)
Frappe Framework: v14.62.1 (version-14)

Ticket: Frappe permission_type is always None · Issue #27042 · frappe/frappe · GitHub