Data Import Tool error NoneType' object has no attribute 'replace'

Hello all !
This is my first post so i would like to thank the developers and the community for all the good work done.

The import of employee .csv fails with error code ‘NoneType’ object has no attribute ‘replace’

What i do :

  • Create 1 employee
  • Data import tool > Export template Employee
  • Click on “Select Mandatory button”
  • Click on “Download witdh data”
  • Empty ID colum and modify Full Name in order to re import new employee
  • import csv
    => Error for row (#21) : ‘NoneType’ object has no attribute ‘replace’

ERPNext: v7.2.6
Frappe Framework: v7.2.5

Thanks,
Xavier

1 Like

Can you share what do you see in your Javascript Console?

desk.min.js:1508 {u’reason_for_leaving’: None, u’personal_email’: None, u’held_on’: None, u’family_background’: None, u’permanent_accommodation_type’: None, u’bank_name’: None, u’naming_series’: u’EMP-‘, u’image’: None, u’creation’: ‘2017-01-09 09:34:14.035463’, u’designation’: None, u’doctype’: u’Employee’, u’salutation’: None, u’holiday_list’: None, u’relation’: None, u’prefered_email’: None, u’place_of_issue’: None, u’owner’: u’Administrator’, u’permanent_address’: None, u’prefered_contact_email’: None, u’company_email’: None, u’feedback’: None, u’education’: [], u’modified_by’: u’Administrator’, u’passport_number’: None, u’resignation_letter_date’: None, u’employee_number’: None, u’emergency_phone_number’: None, u’internal_work_history’: [], u’employment_type’: None, u’salary_mode’: None, u’reports_to’: None, u’date_of_issue’: None, u’date_of_birth’: u’29/11/2010’, u’reason_for_resignation’: None, u’unsubscribed’: 0, u’branch’: None, u’current_accommodation_type’: None, u’employee’: u’EMP-0002’, u’docstatus’: 0, u’current_address’: None, u’leave_approvers’: [], u’status’: u’Active’, u’scheduled_confirmation_date’: None, u’new_workplace’: None, u’parent’: None, u’external_work_history’: [], u’company’: u’PSI INFO’, u’bio’: None, u’leave_encashed’: None, u’bank_ac_no’: None, u’department’: None, u’person_to_be_contacted’: None, u’__islocal’: True, u’date_of_joining’: u’01/12/2016’, u’employee_name’: u’Utilisateur Test 2’, u’final_confirmation_date’: None, u’user_id’: None, u’blood_group’: None, u’name’: u’EMP-0002’, u’idx’: 0, u’cell_number’: None, u’gender’: u’Male’, u’valid_upto’: None, u’modified’: ‘2017-01-09 09:34:14.035463’, u’contract_end_date’: None, u’notice_number_of_days’: 0, u’encashment_date’: None, u’parenttype’: None, u’marital_status’: None, u’health_details’: None, u’relieving_date’: None, u’date_of_retirement’: None, u’parentfield’: None}
desk.min.js:1508 Traceback (most recent call last):
File “/home/frappe/frappe-bench/apps/frappe/frappe/core/page/data_import_tool/importer.py”, line 264, in upload
doc.insert()
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 189, in insert
self.run_before_save_methods()
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 758, in run_before_save_methods
self.run_method(“validate”)
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 655, in run_method
out = Document.hook(fn)(self, *args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 871, in composer
return composed(self, method, *args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 854, in runner
add_to_return_value(self, fn(self, *args, **kwargs))
File “/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py”, line 649, in
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
File “/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/employee/employee.py”, line 42, in validate
self.validate_prefered_email()
File “/home/frappe/frappe-bench/apps/erpnext/erpnext/hr/doctype/employee/employee.py”, line 158, in validate_prefered_email
if not self.get(scrub(self.prefered_contact_email)):
File “/home/frappe/frappe-bench/apps/frappe/frappe/init.py”, line 665, in scrub
return txt.replace(’ ‘,’‘).replace(’-', '').lower()
AttributeError: ‘NoneType’ object has no attribute ‘replace’

we experience exactly the same problem on our end, when trying to import the list of Employees into an ERP Next instance today.

Just in case, below are details on the systems where the issue was detected

  • bench v. 4.1.0
  • Frappe 7.2.15 and 7.2.19
  • ERP Next 7.2.15 and 7.2.19

@rmehta: is there anything the core team at Frappe could perhaps help with?

P.S. Please note the last time we undertook the similar data import effort on behalf of our clients was Nov 2016. At that moment, Employee DocType data import worked like a charm.

Hi. as an addition to George’s post, we found that this error was possibly being caused by the naming_series field.

After removing the column from the import file, we get a new error:

unsupported operand type(s) for +: 'Nonetype' and 'Unicode'

Which, by reference to other threads, is due to the ‘naming_series’ field being empty.

Thanks, in advance!

@rmehta: is there anything the core team at Frappe could perhaps help with?

What kind of help do you need, I think the trace is clear. Maybe the message can be fixed.

@rmehta: we just wondered if the original bug with Data Import Tool (importing data for Employee DocType) has been fixed. If it has not been fixed yet, could you please indicate the relative priority with this fix vs. other pressing items on your shoulders?

This is not a show stopper on our end - just wanted to clarify the timeline with it.

@rmehta
i am also getting the same error. here is my javascript console

 > Traceback (most recent call last):
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
>     doc.save()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 223, in save
>     return self._save(*args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 242, in _save
>     self.insert()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 184, in insert
>     self.set_new_name()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 322, in set_new_name
>     set_new_name(self)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/naming.py", line 38, in set_new_name
>     doc.run_method("autoname")
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 651, in run_method
>     out = Document.hook(fn)(self, *args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 858, in composer
>     return composed(self, method, *args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 841, in runner
>     add_to_return_value(self, fn(self, *args, **kwargs))
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 645, in 
>     fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/website/website_generator.py", line 25, in autoname
>     self.name = self.scrub(self.get(self.website.page_title_field or "title"))
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/website/website_generator.py", line 52, in scrub
>     return cleanup_page_name(text).replace('_', '-')
> AttributeError: 'NoneType' object has no attribute 'replace'

> Traceback (most recent call last):
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/app.py", line 55, in application
>     response = frappe.handler.handle()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/handler.py", line 19, in handle
>     execute_cmd(cmd)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/handler.py", line 40, in execute_cmd
>     ret = frappe.call(method, **frappe.form_dict)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/__init__.py", line 898, in call
>     return fn(*args, **newargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
>     doc.save()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 223, in save
>     return self._save(*args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 242, in _save
>     self.insert()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 184, in insert
>     self.set_new_name()
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 322, in set_new_name
>     set_new_name(self)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/naming.py", line 38, in set_new_name
>     doc.run_method("autoname")
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 651, in run_method
>     out = Document.hook(fn)(self, *args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 858, in composer
>     return composed(self, method, *args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 841, in runner
>     add_to_return_value(self, fn(self, *args, **kwargs))
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py", line 645, in 
>     fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/website/website_generator.py", line 25, in autoname
>     self.name = self.scrub(self.get(self.website.page_title_field or "title"))
>   File "/home/erpnext/frappe-bench/apps/frappe/frappe/website/website_generator.py", line 52, in scrub
>     return cleanup_page_name(text).replace('_', '-')
> AttributeError: 'NoneType' object has no attribute 'replace'

thanks
vivin

I have also hit the same problem importing items from another site which come with existing IDs. Regardless of whether I fill in the column or not on the spreadsheet, the ‘autoname’ function is run which fails as ‘self.naming_series’ is (presumably from the error) set to None. I have worked around it by changing the relevant code in item.py to:

if self.variant_of:
    if not self.item_code:
        template_item_name = frappe.db.get_value("Item", self.variant_of, "item_name")
        self.item_code = make_variant_item_code(self.variant_of, template_item_name, self)
    elif self.item_code:
        pass # He's already got one!
    else:
        from frappe.model.naming import make_autoname
        self.item_code = make_autoname(self.naming_series+'.#####', doc=self)

which simply prevents the autonamer operating if an ID already exists, but this will quite probably break things elsewhere…
It then fails as naming_series isn’t set, which I have further bodged by hardcoding at the end of autoname.

I think:
a) the naming_series should either be in the spreadsheet or pulled from the database, but it should be set for new Item docs when created by the importer, and,
b) the autonamer shouldn’t clobber IDs where they have been set for that item (and don’t conflict with existing items).