diff --git a/bids/layout/layout.py b/bids/layout/layout.py
index bf6319e4..e9f9e8cc 100644
--- a/bids/layout/layout.py
+++ b/bids/layout/layout.py
@@ -6,6 +6,7 @@ from io import open
 from functools import reduce, partial
 from itertools import chain
 import copy
+import warnings
 
 from bids_validator import BIDSValidator
 from ..utils import listify, natural_sort, check_path_matches_patterns
@@ -117,6 +118,8 @@ class BIDSLayout(object):
             the paths to one or more derivatives directories to index. If False
             or None, the derivatives/ directory is ignored during indexing, and
             derivatives will have to be added manually via add_derivatives().
+            Note: derivatives datasets MUST contain a dataset_description.json
+            file in order to be indexed.
         config (str, list): Optional name(s) of configuration file(s) to use.
             By default (None), uses 'bids'.
         sources (BIDLayout, list): Optional BIDSLayout(s) from which the
@@ -356,6 +359,10 @@ class BIDSLayout(object):
                 pipeline directory (e.g., derivatives/fmriprep).
             kwargs (dict): Optional keyword arguments to pass on to
                 BIDSLayout() when initializing each of the derivative datasets.
+
+        Note: Every derivatives directory intended for indexing MUST contain a
+            valid dataset_description.json file. See the BIDS-Derivatives
+            specification for details.
         '''
         paths = listify(path)
         deriv_dirs = []
@@ -378,6 +385,14 @@ class BIDSLayout(object):
                         if check_for_description(sd):
                             deriv_dirs.append(sd)
 
+        if not deriv_dirs:
+            warnings.warn("Derivative indexing was enabled, but no valid "
+                          "derivatives datasets were found in any of the "
+                          "provided or default locations. Please make sure "
+                          "all derivatives datasets you intend to index "
+                          "contain a 'dataset_description.json' file, as "
+                          "described in the BIDS-derivatives specification.")
+
         for deriv in deriv_dirs:
             dd = os.path.join(deriv, 'dataset_description.json')
             with open(dd, 'r', encoding='utf-8') as ddfd:

Derivatives indexing fails silently for deriv directories that lack a `dataset_description.json` file
I have a set of derivatives files that look like this:

derivatives/rt/sub-02/func/sub-02_task-dts_meanRT.tsv

they seem to pass the validator fine, but I get nothing when I use .get(scope='derivatives'):

```
In [35]: layout2 = BIDSLayout(args.bids_dir, derivatives=True)

In [36]: layout2.get(scope='derivatives')
Out[36]: []

```
diff --git a/bids/layout/tests/test_layout.py b/bids/layout/tests/test_layout.py
index acbcc239..f5e2d59d 100644
--- a/bids/layout/tests/test_layout.py
+++ b/bids/layout/tests/test_layout.py
@@ -448,6 +448,21 @@ def test_parse_file_entities_from_layout(layout_synthetic):
     assert target == layout.parse_file_entities(filename, config='derivatives')
 
 
+def test_deriv_indexing():
+    data_dir = join(get_test_data_path(), 'ds005')
+    deriv_dir = join(data_dir, 'derivatives', 'bbr')
+
+    # missing dataset_description.json
+    with pytest.warns(UserWarning):
+        layout = BIDSLayout(data_dir, derivatives=deriv_dir)
+
+    # Should work fine
+    deriv_dir = join(data_dir, 'derivatives', 'events')
+    layout = BIDSLayout(data_dir, derivatives=deriv_dir)
+    assert layout.get(scope='derivatives')
+    assert layout.get(scope='events')
+    assert not layout.get(scope='nonexistent')
+
 def test_add_config_paths():
     bids_dir = dirname(bids.__file__)
     bids_json = os.path.join(bids_dir, 'layout', 'config', 'bids.json')

pip install -e .[analysis]
parse_log_pytest
pytest
pytest pytest-xdist pytest-cov pytest-mock
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==25.3.0
bids-validator==1.14.7.post0
bidsschematools==1.0.4
click==8.1.8
coverage==7.8.0
docopt==0.6.2
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
execnet==2.1.1
importlib_resources==6.5.2
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
jsonschema==4.23.0
jsonschema-specifications==2024.10.1
nibabel==5.3.2
num2words==0.5.14
numpy==2.0.2
packaging @ file:///croot/packaging_1734472117206/work
pandas==2.2.3
patsy==1.0.1
pluggy @ file:///croot/pluggy_1733169602837/work
-e git+https://github.com/bids-standard/pybids.git@169e51bb62fb81185a2ba9e13fffe4d7b7377d14#egg=pybids
pytest @ file:///croot/pytest_1738938843180/work
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
referencing==0.36.2
rpds-py==0.24.0
scipy==1.13.1
six==1.17.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
typing_extensions==4.13.0
tzdata==2025.2
zipp==3.21.0

name: pybids
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==25.3.0
      - bids-validator==1.14.7.post0
      - bidsschematools==1.0.4
      - click==8.1.8
      - coverage==7.8.0
      - docopt==0.6.2
      - execnet==2.1.1
      - importlib-resources==6.5.2
      - jsonschema==4.23.0
      - jsonschema-specifications==2024.10.1
      - nibabel==5.3.2
      - num2words==0.5.14
      - numpy==2.0.2
      - pandas==2.2.3
      - patsy==1.0.1
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.2
      - referencing==0.36.2
      - rpds-py==0.24.0
      - scipy==1.13.1
      - six==1.17.0
      - typing-extensions==4.13.0
      - tzdata==2025.2
      - zipp==3.21.0
prefix: /opt/conda/envs/pybids

bids/layout/tests/test_layout.py::test_deriv_indexing
bids/layout/tests/test_layout.py::test_to_df
bids/layout/tests/test_layout.py::test_layout_init bids/layout/tests/test_layout.py::test_layout_repr bids/layout/tests/test_layout.py::test_layout_copy bids/layout/tests/test_layout.py::test_load_description bids/layout/tests/test_layout.py::test_get_file bids/layout/tests/test_layout.py::test_get_metadata bids/layout/tests/test_layout.py::test_get_metadata2 bids/layout/tests/test_layout.py::test_get_metadata3 bids/layout/tests/test_layout.py::test_get_metadata4 bids/layout/tests/test_layout.py::test_get_metadata_meg bids/layout/tests/test_layout.py::test_get_metadata5 bids/layout/tests/test_layout.py::test_get_metadata_via_bidsfile bids/layout/tests/test_layout.py::test_get_with_bad_target bids/layout/tests/test_layout.py::test_get_bvals_bvecs bids/layout/tests/test_layout.py::test_get_subjects bids/layout/tests/test_layout.py::test_get_fieldmap bids/layout/tests/test_layout.py::test_get_fieldmap2 bids/layout/tests/test_layout.py::test_bids_json bids/layout/tests/test_layout.py::test_get_return_type_dir bids/layout/tests/test_layout.py::test_get_return_sorted bids/layout/tests/test_layout.py::test_force_index bids/layout/tests/test_layout.py::test_layout_with_derivs bids/layout/tests/test_layout.py::test_layout_with_multi_derivs bids/layout/tests/test_layout.py::test_query_derivatives bids/layout/tests/test_layout.py::test_get_bidsfile_image_prop bids/layout/tests/test_layout.py::test_restricted_words_in_path bids/layout/tests/test_layout.py::test_derivative_getters bids/layout/tests/test_layout.py::test_get_tr bids/layout/tests/test_layout.py::test_parse_file_entities bids/layout/tests/test_layout.py::test_parse_file_entities_from_layout bids/layout/tests/test_layout.py::test_add_config_paths
bids/layout/layout.py
bids/layout/layout.py