# Buggy code
def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs):
    """
    Emits something to a session attached to the object.

    Args:
        text (str or tuple, optional): The message to send. This
            is treated internally like any send-command, so its
            value can be a tuple if sending multiple arguments to
            the `text` oob command.
        from_obj (obj, optional): object that is sending. If
            given, at_msg_send will be called. This value will be
            passed on to the protocol.
        session (Session or list, optional): Session or list of
            Sessions to relay data to, if any. If set, will force send
            to these sessions. If unset, who receives the message
            depends on the MULTISESSION_MODE.
        options (dict, optional): Message-specific option-value
            pairs. These will be applied at the protocol level.
    Kwargs:
        any (string or tuples): All kwarg keys not listed above
            will be treated as send-command names and their arguments
            (which can be a string or a tuple).

    Notes:
        `at_msg_receive` will be called on this Object.
        All extra kwargs will be passed on to the protocol.

    """
    # try send hooks
    if from_obj:
        try:
            from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
        except Exception:
            logger.log_trace()
    try:
        if not self.at_msg_receive(text=text, **kwargs):
            # if at_msg_receive returns false, we abort message to this object
            return
    except Exception:
        logger.log_trace()

    kwargs["options"] = options

    # relay to session(s)
    sessions = make_iter(session) if session else self.sessions.all()
    for session in sessions:
        session.data_out(text=text, **kwargs)


# Traceback (AttributeError)
Traceback (most recent call last):
File "/home/avenew/evennia/evennia/objects/objects.py", line 511, in msg
from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
AttributeError: 'list' object has no attribute 'at_msg_send'

# Fixed code
def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs):
    """
    Emits something to a session attached to the object.

    Args:
        text (str or tuple, optional): The message to send. This
            is treated internally like any send-command, so its
            value can be a tuple if sending multiple arguments to
            the `text` oob command.
        from_obj (obj or list, optional): object that is sending. If
            given, at_msg_send will be called. This value will be
            passed on to the protocol. If iterable, will execute hook
            on all entities in it.
        session (Session or list, optional): Session or list of
            Sessions to relay data to, if any. If set, will force send
            to these sessions. If unset, who receives the message
            depends on the MULTISESSION_MODE.
        options (dict, optional): Message-specific option-value
            pairs. These will be applied at the protocol level.
    Kwargs:
        any (string or tuples): All kwarg keys not listed above
            will be treated as send-command names and their arguments
            (which can be a string or a tuple).

    Notes:
        `at_msg_receive` will be called on this Object.
        All extra kwargs will be passed on to the protocol.

    """
    # try send hooks
    if from_obj:
        for obj in make_iter(from_obj):
            try:
                obj.at_msg_send(text=text, to_obj=self, **kwargs)
            except Exception:
                logger.log_trace()
    try:
        if not self.at_msg_receive(text=text, **kwargs):
            # if at_msg_receive returns false, we abort message to this object
            return
    except Exception:
        logger.log_trace()

    kwargs["options"] = options

    # relay to session(s)
    sessions = make_iter(session) if session else self.sessions.all()
    for session in sessions:
        session.data_out(text=text, **kwargs)