# Buggy code
def send_vip(
    self,
    peer,
    subsystem,
    args=None,
    msg_id=b"",
    user=b"",
    via=None,
    flags=0,
    copy=True,
    track=False,
):
    """Send an entire VIP message by individual parts.

    This method will raise a ProtocolError exception if the previous
    send was made with the SNDMORE flag or if other protocol
    constraints are violated. If SNDMORE flag is used, additional
    arguments may be sent. via is required for ROUTER sockets.
    """
    self.wait_send(flags)
    state = self._send_state
    if state > 0:
        raise ProtocolError("previous send operation is not complete")
    elif state == -1:
        if via is None:
            raise ValueError("missing 'via' argument required by ROUTER sockets")
        self.send(via, flags=flags | SNDMORE, copy=copy, track=track)
    if msg_id is None:
        msg_id = b""
    if user is None:
        user = b""
    more = SNDMORE if args else 0
    self.send_multipart(
        [peer, user, msg_id, subsystem], flags=flags | more, copy=copy, track=track
    )
    if args:
        send = self.send if isinstance(args, basestring) else self.send_multipart
        send(args, flags=flags, copy=copy, track=track)


# Traceback (ProtocolError)
Traceback (most recent call last):
File "/home/kyle/workspaces/volttron/env/local/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
result = self._run(*self.args, **self.kwargs)
File "/home/kyle/workspaces/volttron/volttron/platform/vip/agent/subsystems/pubsub.py", line 280, in subscribe
self.rpc().call(peer, 'pubsub.subscribe', prefix, bus=bus).get()
File "/home/kyle/workspaces/volttron/volttron/platform/vip/agent/subsystems/rpc.py", line 282, in call
self.core().socket.send_vip(peer, 'RPC', [request], msg_id=ident)
File "/home/kyle/workspaces/volttron/volttron/platform/vip/socket.py", line 225, in send_vip
raise ProtocolError('previous send operation is not complete')
ProtocolError: previous send operation is not complete
<Greenlet at 0xb2fc002cL: subscribe(<volttron.platform.vip.agent.subsystems.pubsub.Pub, peer='pubsub', callback=<bound method ActuatorAgent.handle_set of <__main_, prefix=Topic(u'devices/actuators/set'))> failed with ProtocolError

Traceback (most recent call last):
File "/home/kyle/workspaces/volttron/env/local/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
result = self._run(*self.args, **self.kwargs)
File "/home/kyle/workspaces/volttron/volttron/platform/vip/agent/subsystems/pubsub.py", line 280, in subscribe
self.rpc().call(peer, 'pubsub.subscribe', prefix, bus=bus).get()
File "/home/kyle/workspaces/volttron/volttron/platform/vip/agent/subsystems/rpc.py", line 282, in call
self.core().socket.send_vip(peer, 'RPC', [request], msg_id=ident)
File "/home/kyle/workspaces/volttron/volttron/platform/vip/socket.py", line 225, in send_vip
raise ProtocolError('previous send operation is not complete')
ProtocolError: previous send operation is not complete
<Greenlet at 0xb2fc007cL: subscribe(<volttron.platform.vip.agent.subsystems.pubsub.Pub, peer='pubsub', callback=<bound method ActuatorAgent.handle_schedule_reques, prefix=Topic(u'devices/actuators/schedule/request'))> failed with ProtocolError

# Fixed code
def send_vip(
    self,
    peer,
    subsystem,
    args=None,
    msg_id=b"",
    user=b"",
    via=None,
    flags=0,
    copy=True,
    track=False,
):
    """Send an entire VIP message by individual parts.

    This method will raise a ProtocolError exception if the previous
    send was made with the SNDMORE flag or if other protocol
    constraints are violated. If SNDMORE flag is used, additional
    arguments may be sent. via is required for ROUTER sockets.
    """
    with self._sending(flags) as flags:
        state = self._send_state
        if state > 0:
            raise ProtocolError("previous send operation is not complete")
        elif state == -1:
            if via is None:
                raise ValueError("missing 'via' argument required by ROUTER sockets")
            self.send(via, flags=flags | SNDMORE, copy=copy, track=track)
        if msg_id is None:
            msg_id = b""
        if user is None:
            user = b""
        more = SNDMORE if args else 0
        self.send_multipart(
            [peer, user, msg_id, subsystem], flags=flags | more, copy=copy, track=track
        )
        if args:
            send = self.send if isinstance(args, basestring) else self.send_multipart
            send(args, flags=flags, copy=copy, track=track)