# Buggy code
def makedirs(self, path):
    self._sftp_connect()

    if self.isdir(path):
        return

    if self.isfile(path) or self.islink(path):
        raise DvcException("a file with the same name '{}' already exists".format(path))

    head, tail = posixpath.split(path)

    if head:
        self.makedirs(head)

    if tail:
        self._sftp.mkdir(path)


# Traceback (OSError)
DEBUG: SELECT count from state_info WHERE rowid=1
DEBUG: fetched: [(33301,)]
DEBUG: UPDATE state_info SET count = 33301 WHERE rowid = 1
DEBUG: Path /home/rob/fossid/dvc/autoid-dvc/.dvc/cache inode 6554341
DEBUG: INSERT OR REPLACE INTO state(inode, size, mtime, timestamp, md5) VALUES (6554341, "44515650", "1554877442274173184", "1554879861734038784", "")
ERROR: failed to push data to the cloud - 'host'
------------------------------------------------------------
Traceback (most recent call last):
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/ssh/__init__.py", line 187, in upload
from_info["path"], to_info["path"], progress_title=name
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/ssh/connection.py", line 189, in upload
self.makedirs(posixpath.dirname(dest))
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/ssh/connection.py", line 127, in makedirs
self._sftp.mkdir(path)
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/paramiko/sftp_client.py", line 460, in mkdir
self._request(CMD_MKDIR, path, attr)
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/paramiko/sftp_client.py", line 813, in _request
return self._read_response(num)
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/paramiko/sftp_client.py", line 865, in _read_response
self._convert_status(msg)
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/paramiko/sftp_client.py", line 898, in _convert_status
raise IOError(text)
OSError: Failure

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/command/data_sync.py", line 66, in do_run
recursive=self.args.recursive,
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/repo/push.py", line 27, in push
used, jobs, remote=remote, show_checksums=show_checksums
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/data_cloud.py", line 132, in push
show_checksums=show_checksums,
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/local.py", line 713, in push
download=False,
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/local.py", line 703, in _process
f.result()
File "/usr/lib/python3.6/concurrent/futures/_base.py", line 425, in result
return self.__get_result()
File "/usr/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result
raise self._exception
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/rob/fossid/dvc/.venv/lib/python3.6/site-packages/dvc/remote/ssh/__init__.py", line 192, in upload
host=from_info["host"],
KeyError: 'host'
------------------------------------------------------------

Having any troubles?. Hit us up at https://dvc.org/support, we are always happy to help!
DEBUG: Analytics is enabled.
DEBUG: Trying to spawn '['/home/rob/fossid/dvc/.venv/bin/python3', '-m', 'dvc', 'daemon', '-q', 'analytics', '/tmp/tmplvf38zmb']'
DEBUG: Spawned '['/home/rob/fossid/dvc/.venv/bin/python3', '-m', 'dvc', 'daemon', '-q', 'analytics', '/tmp/tmplvf38zmb']'

# Fixed code
def makedirs(self, path):
    self._sftp_connect()

    # Single stat call will say whether this is a dir, a file or a link
    st_mode = self.st_mode(path)

    if stat.S_ISDIR(st_mode):
        return

    if stat.S_ISREG(st_mode) or stat.S_ISLNK(st_mode):
        raise DvcException("a file with the same name '{}' already exists".format(path))

    head, tail = posixpath.split(path)

    if head:
        self.makedirs(head)

    if tail:
        try:
            self._sftp.mkdir(path)
        except IOError as e:
            # Since paramiko errors are very vague we need to recheck
            # whether it's because path already exists or something else
            if e.errno == errno.EACCES or not self.exists(path):
                raise