Bench update 11: Item cannot be added to its own descendents

After update the error goes like this

Executing erpnext.patches.v11_0.rename_supplier_type_to_supplier_group in site1.local (1bd3e0294da19198)
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 97, in <module>
    main()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 25, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 222, in migrate
    migrate(context.verbose, rebuild_website=rebuild_website)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 39, in migrate
    frappe.modules.patch_handler.run_all()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 29, in run_all
    if not run_single(patchmodule = patch):
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 63, in run_single
    return execute_patch(patchmodule, method, methodargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/patch_handler.py", line 83, in execute_patch
    frappe.get_attr(patchmodule.split()[0] + ".execute")()
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py", line 21, in execute
    build_tree()
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py", line 32, in build_tree
    }).insert(ignore_permissions=True)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 249, in insert
    self.run_post_save_methods()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 898, in run_post_save_methods
    self.run_method("on_update")
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 765, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1040, in composer
    return composed(self, method, *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 1023, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 759, in <lambda>
    fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/setup/doctype/supplier_group/supplier_group.py", line 19, in on_update
    self.update_nsm_model()
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/setup/doctype/supplier_group/supplier_group.py", line 16, in update_nsm_model
    frappe.utils.nestedset.update_nsm(self)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/nestedset.py", line 40, in update_nsm
    update_add_node(doc, p or '', pf)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/nestedset.py", line 64, in update_add_node
    validate_loop(doc.doctype, doc.name, left, right)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/nestedset.py", line 181, in validate_loop
    frappe.throw(_("Item cannot be added to its own descendents"), NestedSetRecursionError)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 327, in throw
    msgprint(msg, raise_exception=exc, title=title, indicator='red')
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 313, in msgprint
    _raise_exception()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 286, in _raise_exception
    raise raise_exception(msg)
frappe.utils.nestedset.NestedSetRecursionError: Item cannot be added to its own descendents

I restored the database but the error still exists when bench migrate.

Should I delete the site1.local and restore the database ?
Please help.

Yep. Welcome to install hell.

The underlying issue is the change from supplier type (a list) to supplier group (a tree). I’m not sure this change was really necessary (to better visualize a long supply chain? I really don’t know), but I’m in favor of better views generally and this facilitates that. The problem with existing data is that the patch created a new blank field (parent) for which only one record can be blank (root). The rest need to have have another supplier group introduced. This patch should make all suppliers children of the parent “All Supplier Groups” by default but it does not.

I would delete and restore, but you will also need to pin ERPNext and Frappe to 10.3.31 before you do, or you’ll just reintroduce breaking changes again.

git checkout v10.1.31 . ← the trailing " . " is important

Alternatively (and if you’re a confident SQL person), you can directly edit the parent fields and insert a new record. Take a backup of your DB first with one of these:
mysql -u root -p dbname > backupfile.sql

2 Likes

One solution I found was to comment it in patches.txt . That solved the problem .FOR NOW.

That’s smart. Better than my method, actually.

Commenting patches is not at all right and also not a recommended way

Checkout to master (i.e, V10 and stable) branch then restore the backup and then run bench migrate.

where do commit it, i have the same issue

@rameshprasathag, per @saurabh6790, commenting out the patch is not advised. The solution he proposed is much safer. But if you want to live dangerously it’s in apps/erpnext/erpnext/patches.txt Remember there are no warranties here.

Hi can you explain briefly, because i am new to the erpnext.
Thanks.

I belive there is a problem with this patch. Can I wait so as someone to find the solution and then uncomment the patch?

Fixing via [fix] add ignore validate flag by saurabh6790 · Pull Request #14238 · frappe/erpnext · GitHub

Bench now offers an option to run bench migrate --skip-failing.