Repository: iterative/dvc

Issue:
unexpected error - tuple index out of range
# Bug Report


## import: crashes with no imported files

## Description
We have a NAS that serves both as the home of a data registry and a shared cache. We can suddenly not `dvc import` data from that registry any more.
```console
$ dvc import /home/shared/data/app-data-registry/ app_data   
Importing 'app_data (/home/shared/data/app-data-registry/)' -> 'app_data'
ERROR: unexpected error - tuple index out of range                                                                                                                                                                                                                                                                                                                                          

Having any troubles? Hit us up at https://dvc.org/support, we are always happy to help!
```

### Reproduce
Not sure what is expected here, we did follow approximately the data registry and shared cache tutorials. I'll happily provide more details if you tell me what to provide.


**Output of `dvc doctor`:**

```console
$ dvc doctor    
DVC version: 2.45.1 (pip)
-------------------------
Platform: Python 3.10.6 on Linux-5.19.0-32-generic-x86_64-with-glibc2.35
Subprojects:
	dvc_data = 0.40.3
	dvc_objects = 0.19.3
	dvc_render = 0.2.0
	dvc_task = 0.1.11
	dvclive = 2.0.0
	scmrepo = 0.1.11
Supports:
	http (aiohttp = 3.8.3, aiohttp-retry = 2.8.3),
	https (aiohttp = 3.8.3, aiohttp-retry = 2.8.3),
	s3 (s3fs = 2023.1.0, boto3 = 1.26.58)
Cache types: <https://error.dvc.org/no-dvc-cache>
Caches: local
Remotes: None
Workspace directory: ext4 on /dev/mapper/vgubuntu-root
Repo: dvc (subdir), git
```

**Verbose output:**

```console
$ dvc import /home/shared/data/app-data-registry/ app_data -v
2023-02-23 13:47:45,225 DEBUG: v2.45.1 (pip), CPython 3.10.6 on Linux-5.19.0-32-generic-x86_64-with-glibc2.35
2023-02-23 13:47:45,225 DEBUG: command: /home/johan/dev/vAll/bin/dvc import /home/shared/data/app-data-registry/ app_data -v
2023-02-23 13:47:45,412 DEBUG: Removing output 'app_data' of stage: 'app_data.dvc'.
2023-02-23 13:47:45,412 DEBUG: Removing '/home/johan/dev/app-object-detection/datasets/sources/app_data'
Importing 'app_data (/home/shared/data/app-data-registry/)' -> 'app_data'
2023-02-23 13:47:45,413 DEBUG: Computed stage: 'app_data.dvc' md5: '83cee60bb2a8d320adb7d1888b62442e'
2023-02-23 13:47:45,413 DEBUG: 'md5' of stage: 'app_data.dvc' changed.
2023-02-23 13:47:45,413 DEBUG: Creating external repo /home/shared/data/app-data-registry/@None
2023-02-23 13:47:45,414 DEBUG: erepo: git clone '/home/shared/data/app-data-registry/' to a temporary dir
2023-02-23 13:47:45,740 DEBUG: Checking if stage '/app_data' is in 'dvc.yaml'                                                                                                                                                                                                                                                                                                               
2023-02-23 13:47:45,741 ERROR: unexpected error - tuple index out of range
Traceback (most recent call last):
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/output.py", line 1011, in get_dir_cache
    ocheck(self.cache, obj)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_data/hashfile/__init__.py", line 20, in check
    odb.check(obj.oid, **kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_data/hashfile/db/__init__.py", line 183, in check
    _, actual = hash_file(obj.path, obj.fs, self.hash_name, self.state)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_data/hashfile/hash.py", line 178, in hash_file
    hash_value, meta = _hash_file(path, fs, name, callback=cb, info=info)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_data/hashfile/hash.py", line 121, in _hash_file
    info = info or fs.info(path)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_objects/fs/base.py", line 481, in info
    return self.fs.info(path, **kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc_objects/fs/local.py", line 42, in info
    return self.fs.info(path)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/fsspec/implementations/local.py", line 87, in info
    out = os.stat(path, follow_symlinks=False)
FileNotFoundError: [Errno 2] No such file or directory: '/home/johan/dev/app-object-detection/datasets/sources/.dvc/cache/c0/ea6ef3f856bbcb11da8c2a19c39211.dir'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/cli/__init__.py", line 210, in main
    ret = cmd.do_run()
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/cli/command.py", line 26, in do_run
    return self.run()
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/commands/imp.py", line 17, in run
    self.repo.imp(
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/imp.py", line 6, in imp
    return self.imp_url(path, out=out, fname=fname, erepo=erepo, frozen=True, **kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/__init__.py", line 58, in wrapper
    return f(repo, *args, **kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/scm_context.py", line 151, in run
    return method(repo, *args, **kw)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/imp_url.py", line 91, in imp_url
    stage.run(jobs=jobs, no_download=no_download)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/funcy/decorators.py", line 45, in wrapper
    return deco(call, *dargs, **dkwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/decorators.py", line 43, in rwlocked
    return call()
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/funcy/decorators.py", line 66, in __call__
    return self._func(*self._args, **self._kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/__init__.py", line 577, in run
    self._sync_import(dry, force, kwargs.get("jobs", None), no_download)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/funcy/decorators.py", line 45, in wrapper
    return deco(call, *dargs, **dkwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/decorators.py", line 43, in rwlocked
    return call()
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/funcy/decorators.py", line 66, in __call__
    return self._func(*self._args, **self._kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/__init__.py", line 611, in _sync_import
    sync_import(self, dry, force, jobs, no_download)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/imports.py", line 61, in sync_import
    stage.deps[0].download(
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/dependency/repo.py", line 75, in download
    for odb, objs in self.get_used_objs().items():
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/dependency/repo.py", line 102, in get_used_objs
    used, _, _ = self._get_used_and_obj(**kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/dependency/repo.py", line 124, in _get_used_and_obj
    for odb, obj_ids in repo.used_objs(
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/__init__.py", line 476, in used_objs
    for odb, objs in self.index.used_objs(
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/index.py", line 449, in used_objs
    for odb, objs in stage.get_used_objs(
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/stage/__init__.py", line 722, in get_used_objs
    for odb, objs in out.get_used_objs(*args, **kwargs).items():
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/output.py", line 1100, in get_used_objs
    obj = self._collect_used_dir_cache(**kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/output.py", line 1033, in _collect_used_dir_cache
    self.get_dir_cache(jobs=jobs, remote=remote)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/output.py", line 1015, in get_dir_cache
    self.repo.cloud.pull([obj.hash_info], **kwargs)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/data_cloud.py", line 180, in pull
    odb = odb or self.get_remote_odb(remote, "pull")
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/data_cloud.py", line 105, in get_remote_odb
    remote = self.get_remote(name=name, command=command)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/data_cloud.py", line 78, in get_remote
    config["tmp_dir"] = self.repo.index_db_dir
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/funcy/objects.py", line 28, in __get__
    res = instance.__dict__[self.fget.__name__] = self.fget(instance)
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/__init__.py", line 546, in index_db_dir
    return self._get_database_dir("index")
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/dvc/repo/__init__.py", line 148, in _get_database_dir
    f"{self.fs.path.name(self.root_dir)}-{root_dir_hash[0:7]}",
  File "/home/johan/dev/vAll/lib/python3.10/site-packages/scmrepo/fs.py", line 88, in name
    return self.parts(path)[-1]
IndexError: tuple index out of range

2023-02-23 13:47:45,797 DEBUG: Version info for developers:
DVC version: 2.45.1 (pip)
-------------------------
Platform: Python 3.10.6 on Linux-5.19.0-32-generic-x86_64-with-glibc2.35
Subprojects:
	dvc_data = 0.40.3
	dvc_objects = 0.19.3
	dvc_render = 0.2.0
	dvc_task = 0.1.11
	dvclive = 2.0.0
	scmrepo = 0.1.11
Supports:
	http (aiohttp = 3.8.3, aiohttp-retry = 2.8.3),
	https (aiohttp = 3.8.3, aiohttp-retry = 2.8.3),
	s3 (s3fs = 2023.1.0, boto3 = 1.26.58)
Cache types: <https://error.dvc.org/no-dvc-cache>
Caches: local
Remotes: None
Workspace directory: ext4 on /dev/mapper/vgubuntu-root
Repo: dvc (subdir), git

Having any troubles? Hit us up at https://dvc.org/support, we are always happy to help!
2023-02-23 13:47:45,798 DEBUG: Analytics is enabled.
2023-02-23 13:47:45,823 DEBUG: Trying to spawn '['daemon', '-q', 'analytics', '/tmp/tmpr8fs_15j']'
2023-02-23 13:47:45,824 DEBUG: Spawned '['daemon', '-q', 'analytics', '/tmp/tmpr8fs_15j']'

```



Discussion:

Resolving patch:
diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -126,6 +126,8 @@ def _get_repo_dirs(
         return root_dir, dvc_dir
 
     def _get_database_dir(self, db_name: str) -> Optional[str]:
+        from dvc.fs import localfs
+
         # NOTE: by default, store SQLite-based remote indexes and state's
         # `links` and `md5s` caches in the repository itself to avoid any
         # possible state corruption in 'shared cache dir' scenario, but allow
@@ -138,15 +140,21 @@ def _get_database_dir(self, db_name: str) -> Optional[str]:
 
         import hashlib
 
-        root_dir_hash = hashlib.sha224(self.root_dir.encode("utf-8")).hexdigest()
+        if self.local_dvc_dir:
+            fs: "FileSystem" = localfs
+            local_root = fs.path.parent(self.local_dvc_dir)
+        else:
+            fs = self.fs
+            local_root = self.root_dir
+        root_dir_hash = hashlib.sha224(local_root.encode("utf-8")).hexdigest()
 
-        db_dir = self.fs.path.join(
+        db_dir = fs.path.join(
             base_db_dir,
             self.DVC_DIR,
-            f"{self.fs.path.name(self.root_dir)}-{root_dir_hash[0:7]}",
+            f"{fs.path.name(local_root)}-{root_dir_hash[0:7]}",
         )
 
-        self.fs.makedirs(db_dir, exist_ok=True)
+        fs.makedirs(db_dir, exist_ok=True)
         return db_dir
 
     def __init__(  # noqa: PLR0915


Test patch:
diff --git a/tests/unit/remote/test_remote.py b/tests/unit/remote/test_remote.py
--- a/tests/unit/remote/test_remote.py
+++ b/tests/unit/remote/test_remote.py
@@ -66,6 +66,8 @@ def test_remote_index_dir_config(make_tmp_dir, dvc):
         conf["remote"]["s3"] = {"url": "s3://bucket/name"}
 
     dvc.root_dir = "/usr/local/test_repo"
+    dvc.dvc_dir = "/usr/local/test_repo/.dvc"
+    dvc.__dict__.pop("local_dvc_dir")
 
     assert os.path.dirname(
         get_index(dvc.cloud.get_remote_odb(name="s3")).index_dir