`dvc.api.get_url()` throws error when working directory is a subdirectory of repo path
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 15.9k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
Bug Report
Description
dvc.api.get_url() throws an error when the current working path is a subdirectory inside the dvc repository.
Reproduce
cat > setup.sh << EOF
mkdir -p test_repo
cd test_repo
dvc init --no-scm
mkdir -p /tmp/dvc_remote/
dvc remote add -d storage_name /tmp/dvc_remote/
echo foo > bar.txt
dvc add bar.txt
dvc push bar.txt
mkdir subdir/
EOF
cat > test.py << EOF
import os
from pathlib import Path
from dvc import api
path = "bar.txt"
os.chdir("./test_repo")
repo = os.getcwd()
print("From CWD -> repo root:")
print(f"\t{api.get_url(path=path, repo=repo)}")
os.chdir(Path(repo) / "..")
print("From CWD -> outside repo:")
print(f"\t{api.get_url(path=path, repo=repo)}")
os.chdir(Path(repo) / "subdir")
print("From CWD -> subdir in repo:")
print(f"\t{api.get_url(path=path, repo=repo)}")
EOF
sh setup.sh
python test.py
Expected
I was expecting python test.py file to output the following lines:
From CWD -> repo root:
/tmp/dvc_remote/files/md5/d3/b07384d113edec49eaa6238ad5ff00
From CWD -> outside repo:
/tmp/dvc_remote/files/md5/d3/b07384d113edec49eaa6238ad5ff00
From CWD -> subdir in repo:
/tmp/dvc_remote/files/md5/d3/b07384d113edec49eaa6238ad5ff00
However, only the first two instances were true; the third one (from a subdir in repo) failed:
From CWD -> subdir in repo:
Traceback (most recent call last):
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/dvc/repo/__init__.py", line 401, in get_data_index_entry
return index, index[key]
~~~~~^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/dvc_data/index/index.py", line 838, in __getitem__
return self._trie[key]
~~~~~~~~~~^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/sqltrie/serialized.py", line 58, in __getitem__
raw = self._trie[key]
~~~~~~~~~~^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/sqltrie/sqlite/sqlite.py", line 266, in __getitem__
row = self._get_node(key)
^^^^^^^^^^^^^^^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/sqltrie/sqlite/sqlite.py", line 204, in _get_node
raise KeyError(key)
KeyError: ('subdir', 'bar.txt')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/rgoya/test/test.py", line 19, in <module>
print(f"\t{api.get_url(path=path, repo=repo)}")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/dvc/api/data.py", line 84, in get_url
index, entry = _repo.get_data_index_entry(path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/rgoya/.pixi/envs/default/lib/python3.11/site-packages/dvc/repo/__init__.py", line 403, in get_data_index_entry
raise OutputNotFoundError(path, self) from exc
dvc.exceptions.OutputNotFoundError: Unable to find DVC file with output 'bar.txt'
Environment information
DVC version: 3.67.1 (conda)
---------------------------
Platform: Python 3.11.13 on macOS-26.4-x86_64-i386-64bit
Subprojects:
dvc_data = 3.18.2
dvc_objects = 5.2.0
dvc_render = 1.0.2
dvc_task = 0.40.2
scmrepo = 3.5.2
Supports:
gdrive (pydrive2 = 1.21.3),
http (aiohttp = 3.9.5, aiohttp-retry = 2.9.1),
https (aiohttp = 3.9.5, aiohttp-retry = 2.9.1),
s3 (s3fs = 2025.3.2, boto3 = 1.37.3),
ssh (sshfs = 2025.2.0)
Config:
Global: /Users/rgoya/Library/Application Support/dvc
System: /Library/Application Support/dvc
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at dvc/api/data.py in get_url and dvc/repo/init.py in get_data_index_entry, then reproduce the failure with the working directory set to the repository subdirectory. Trace how the requested path is resolved and add coverage showing that get_url returns the same remote URL from the repository root, outside the repository, and its subdirectory.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100