# Buggy code
def _save_tree(self):
    """recursively traverse back up the tree, save when we reach the root"""
    if self._parent:
        self._parent._save_tree()
    elif self._db_obj:
        self._db_obj.value = self
    else:
        logger.log_err("_SaverMutable %s has no root Attribute to save to." % self)


# Traceback (ValueError)
Traceback (most recent call last):
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/evennia/evennia/commands/cmdhandler.py", line 584, in _run_command
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     ret = cmd.func()
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "./commands/commands/jobs.py", line 447, in func
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     invite_dict[targ] = ticket
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/evennia/evennia/utils/dbserialize.py", line 118, in save_wrapper
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     self._save_tree()
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/evennia/evennia/utils/dbserialize.py", line 145, in _save_tree
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     self._db_obj.value = self
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/evennia/evennia/typeclasses/attributes.py", line 152, in __value_set
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     self.save(update_fields=["db_value"])
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/evennia/evennia/utils/idmapper/models.py", line 382, in save
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     super(SharedMemoryModel, self).save(*args, **kwargs)
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/local/lib/python2.7/site-packages/django/db/models/base.py", line 708, in save
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     force_update=force_update, update_fields=update_fields)
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/local/lib/python2.7/site-packages/django/db/models/base.py", line 736, in save_base
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]   File "/home/tehom/arx/local/lib/python2.7/site-packages/django/db/models/base.py", line 792, in _save_table
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::]     raise ValueError("Cannot force an update in save() with no primary key.")
2017-08-18T16:07:17-0400 [AMPProtocol,0,127.0.0.1] [::] ValueError: Cannot force an update in save() with no primary key.

# Fixed code
def _save_tree(self):
    """recursively traverse back up the tree, save when we reach the root"""
    if self._parent:
        self._parent._save_tree()
    elif self._db_obj:
        if not self._db_obj.pk:
            cls_name = self.__class__.__name__
            non_saver_name = cls_name.lstrip("_Saver")
            err_msg = "%s %s has had its root Attribute deleted." % (cls_name, self)
            err_msg += (
                " It must be cast to a %s before it can be modified further."
                % non_saver_name
            )
            raise ValueError(err_msg)
        self._db_obj.value = self
    else:
        logger.log_err("_SaverMutable %s has no root Attribute to save to." % self)