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:
codecov[bot]: # [Codecov](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative) Report
Base: **92.99**% // Head: **92.48**% // Decreases project coverage by **`-0.52%`** :warning:
> Coverage data is based on head [(`786d2e9`)](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative) compared to base [(`81da91a`)](https://codecov.io/gh/iterative/dvc/commit/81da91a9735d815c8b1beb3b25f35c7d3ae1507b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative).
> Patch coverage: 72.72% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #9078      +/-   ##
==========================================
- Coverage   92.99%   92.48%   -0.52%     
==========================================
  Files         459      459              
  Lines       37064    37072       +8     
  Branches     5359     4352    -1007     
==========================================
- Hits        34468    34286     -182     
- Misses       2070     2207     +137     
- Partials      526      579      +53     
```


| [Impacted Files](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative) | Coverage Δ | |
|---|---|---|
| [dvc/repo/\_\_init\_\_.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-ZHZjL3JlcG8vX19pbml0X18ucHk=) | `90.88% <66.66%> (-0.67%)` | :arrow_down: |
| [tests/unit/remote/test\_remote.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC9yZW1vdGUvdGVzdF9yZW1vdGUucHk=) | `100.00% <100.00%> (ø)` | |
| [dvc/utils/threadpool.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-ZHZjL3V0aWxzL3RocmVhZHBvb2wucHk=) | `63.04% <0.00%> (-30.44%)` | :arrow_down: |
| [tests/unit/test\_rwlock.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC90ZXN0X3J3bG9jay5weQ==) | `77.52% <0.00%> (-22.48%)` | :arrow_down: |
| [tests/func/test\_unprotect.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvZnVuYy90ZXN0X3VucHJvdGVjdC5weQ==) | `78.57% <0.00%> (-21.43%)` | :arrow_down: |
| [tests/unit/test\_api.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC90ZXN0X2FwaS5weQ==) | `83.33% <0.00%> (-16.67%)` | :arrow_down: |
| [tests/unit/utils/test\_utils.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC91dGlscy90ZXN0X3V0aWxzLnB5) | `83.33% <0.00%> (-16.67%)` | :arrow_down: |
| [tests/unit/test\_daemon.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC90ZXN0X2RhZW1vbi5weQ==) | `85.18% <0.00%> (-14.82%)` | :arrow_down: |
| [dvc/utils/fs.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-ZHZjL3V0aWxzL2ZzLnB5) | `83.63% <0.00%> (-10.91%)` | :arrow_down: |
| [tests/unit/proc/test\_manager.py](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative#diff-dGVzdHMvdW5pdC9wcm9jL3Rlc3RfbWFuYWdlci5weQ==) | `89.28% <0.00%> (-10.72%)` | :arrow_down: |
| ... and [33 more](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/iterative/dvc/pull/9078?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iterative).


Patch:
diff --git a/dvc/commands/data_sync.py b/dvc/commands/data_sync.py
index ce84d05a8..a04b8f602 100644
--- a/dvc/commands/data_sync.py
+++ b/dvc/commands/data_sync.py
@@ -40,6 +40,7 @@ class CmdDataPull(CmdDataBase):
                 recursive=self.args.recursive,
                 run_cache=self.args.run_cache,
                 glob=self.args.glob,
+                allow_missing=self.args.allow_missing,
             )
             self.log_summary(stats)
         except (CheckoutError, DvcException) as exc:
@@ -197,6 +198,12 @@ def add_parser(subparsers, _parent_parser):
         default=False,
         help=argparse.SUPPRESS,
     )
+    pull_parser.add_argument(
+        "--allow-missing",
+        action="store_true",
+        default=False,
+        help="Ignore errors if some of the files or directories are missing.",
+    )
     pull_parser.set_defaults(func=CmdDataPull)
 
     # Push
diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py
index 635f1085b..bd89fbd8e 100644
--- a/dvc/repo/__init__.py
+++ b/dvc/repo/__init__.py
@@ -126,6 +126,8 @@ class Repo:
         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 @@ class Repo:
 
         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
diff --git a/dvc/repo/experiments/show.py b/dvc/repo/experiments/show.py
index ab1052a88..7cde987b8 100644
--- a/dvc/repo/experiments/show.py
+++ b/dvc/repo/experiments/show.py
@@ -197,6 +197,7 @@ def _collect_branch(
     repo: "Repo",
     baseline: str,
     running: Dict[str, Any],
+    refs: Optional[Iterable[str]] = None,
     **kwargs,
 ) -> Dict[str, Dict[str, Any]]:
     results: Dict[str, Dict[str, Any]] = OrderedDict()
@@ -215,7 +216,11 @@ def _collect_branch(
     commits: List[Tuple[str, "GitCommit", str, List[str]]] = []
 
     assert isinstance(repo.scm, Git)
-    for ref in repo.scm.iter_refs(base=str(ref_info)):
+    if refs:
+        ref_it = (ref for ref in iter(refs) if ref.startswith(str(ref_info)))
+    else:
+        ref_it = repo.scm.iter_refs(base=str(ref_info))
+    for ref in ref_it:
         try:
             commit = repo.scm.resolve_commit(ref)
             exp_rev = resolve_rev(repo.scm, ref)
@@ -244,19 +249,22 @@ def _collect_branch(
 
 
 def get_branch_names(
-    scm: "Git", baseline_set: Iterable[str]
+    scm: "Git", baseline_set: Iterable[str], refs: Optional[Iterable[str]] = None
 ) -> Dict[str, Optional[str]]:
     names: Dict[str, Optional[str]] = {}
-    for base in [
+    bases = [
         f"refs/exps/{baseline[:2]}/{baseline[2:]}/" for baseline in baseline_set
-    ] + ["refs/heads/", "refs/tags/"]:
-        for ref in scm.iter_refs(base=base):
-            if ref:
+    ] + ["refs/heads/", "refs/tags/"]
+    ref_it = iter(refs) if refs else scm.iter_refs()
+    for ref in ref_it:
+        for base in bases:
+            if ref.startswith(base):
                 try:
                     rev = scm.get_ref(ref)
                     names[rev] = ref[len(base) :]
                 except KeyError:
-                    logger.debug("unreosolved ref %s", ref)
+                    logger.debug("unresolved ref %s", ref)
+                break
     logger.debug("found refs for revs: %s", names)
     return names
 
@@ -441,7 +449,8 @@ def show(  # noqa: PLR0913
     found_revs.update(
         iter_revs(repo.scm, revs, num, all_branches, all_tags, all_commits)
     )
-    branch_names = get_branch_names(repo.scm, found_revs)
+    cached_refs = list(repo.scm.iter_refs())
+    branch_names = get_branch_names(repo.scm, found_revs, refs=cached_refs)
 
     running: Dict[str, Dict] = repo.experiments.get_running_exps(
         fetch_refs=fetch_running
@@ -489,6 +498,7 @@ def show(  # noqa: PLR0913
             param_deps=param_deps,
             onerror=onerror,
             force=force,
+            refs=cached_refs,
         )
 
     update_new(res, failed_experiments)
diff --git a/dvc/repo/pull.py b/dvc/repo/pull.py
index 93ae72f6c..300847581 100644
--- a/dvc/repo/pull.py
+++ b/dvc/repo/pull.py
@@ -25,6 +25,7 @@ def pull(  # noqa: PLR0913
     run_cache=False,
     glob=False,
     odb: Optional["ObjectDB"] = None,
+    allow_missing=False,
 ):
     if isinstance(targets, str):
         targets = [targets]
@@ -48,6 +49,7 @@ def pull(  # noqa: PLR0913
         with_deps=with_deps,
         force=force,
         recursive=recursive,
+        allow_missing=allow_missing,
     )
 
     stats["fetched"] = processed_files_count


Test patch:
diff --git a/tests/func/test_data_cloud.py b/tests/func/test_data_cloud.py
index 1f5e59ae5..286e01ce1 100644
--- a/tests/func/test_data_cloud.py
+++ b/tests/func/test_data_cloud.py
@@ -7,6 +7,7 @@ from flaky.flaky_decorator import flaky
 
 import dvc_data
 from dvc.cli import main
+from dvc.exceptions import CheckoutError
 from dvc.external_repo import clean_repos
 from dvc.stage.exceptions import StageNotFound
 from dvc.testing.remote_tests import TestRemote  # noqa, pylint: disable=unused-import
@@ -561,3 +562,17 @@ def test_target_remote(tmp_dir, dvc, make_remote):
         "6b18131dc289fd37006705affe961ef8.dir",
         "b8a9f715dbb64fd5c56e7783c6820a61",
     }
+
+
+def test_pull_allow_missing(tmp_dir, dvc, local_remote):
+    dvc.stage.add(name="bar", outs=["bar"], cmd="echo bar > bar")
+
+    with pytest.raises(CheckoutError):
+        dvc.pull()
+
+    tmp_dir.dvc_gen("foo", "foo")
+    dvc.push()
+    clean(["foo"], dvc)
+
+    stats = dvc.pull(allow_missing=True)
+    assert stats["fetched"] == 1
diff --git a/tests/unit/command/test_data_sync.py b/tests/unit/command/test_data_sync.py
index 776b56955..a8eca7ad2 100644
--- a/tests/unit/command/test_data_sync.py
+++ b/tests/unit/command/test_data_sync.py
@@ -58,6 +58,7 @@ def test_pull(mocker):
             "--recursive",
             "--run-cache",
             "--glob",
+            "--allow-missing",
         ]
     )
     assert cli_args.func == CmdDataPull
@@ -79,6 +80,7 @@ def test_pull(mocker):
         recursive=True,
         run_cache=True,
         glob=True,
+        allow_missing=True,
     )
 
 
diff --git a/tests/unit/remote/test_remote.py b/tests/unit/remote/test_remote.py
index 2820e1ba4..0847a779c 100644
--- 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