XCP-D: FileNotFoundError: No BOLD NIfTI or transforms found to allowed space

Summary of what happened:

I ran XCP-d on a fmriprepped dataset, most subjects (~80%) ran fine, the rest seems to crash with FileNotFoundError: No BOLD NIfTI or transforms found to allowed space even though these files are clearly present in the right location. Seems like most of the failed subjects had multiple sessions of data, but there were some subjects with multiple sessions of data that ran fine.

Command used (and if a helper script was used, a link to the helper script or the command generated):

singularity run --cleanenv $HOME/XCP_d \
$fmriprep_dir $output_dir participant -w $work_dir/sub-A00086474 \
--mode linc \
--participant-label sub-A00086474 \
--linc-qc n \
--combine-runs n \
--smoothing 0 \
--skip-parcellation \
--omp-nthreads 4 \
--nthreads 4 \
--md-only-boilerplate

Version:

XCP-d 26.0.2

fmriprep 25.2.4

Data formatted according to a validatable standard? Please provide the output of the validator:

PASTE VALIDATOR OUTPUT HERE

Relevant log outputs (up to 20 lines):

A valid FreeSurfer license file is recommended. Set the FS_LICENSE environment variable or use the '--fs-license-file' flag.
Framewise displacement-based scrubbing is disabled. The following parameters will have no effect:
	--min-time
260428-21:55:51,202 nipype.workflow IMPORTANT:
	 Running XCP-D version 26.0.2
260428-21:55:51,203 nipype.workflow WARNING:
	 Previous output generated by version 0+unknown found.
260428-21:56:01,410 nipype.workflow IMPORTANT:
	 Building XCP-D's workflow:
           * Preprocessing derivatives path: /scratch/junhong.yu/NKI/output.
           * Participant list: ['A00086474'].
           * Run identifier: 20260428-215441_ce2c4ca7-dbcb-4833-8922-a238206b9461.
           * Searching for derivatives and atlases: {'xcpdatlases': PosixPath('/home/xcp_d/.cache/xcp_d/XCPDAtlases'), 'xcpd4s': PosixPath('/home/xcp_d/.cache/xcp_d/AtlasPack')}.
Process Process-2:
Traceback (most recent call last):
  File "/app/.pixi/envs/xcp-d/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/app/.pixi/envs/xcp-d/lib/python3.12/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/cli/workflow.py", line 94, in build_workflow
    retval['workflow'] = init_xcpd_wf()
                         ^^^^^^^^^^^^^^
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/workflows/base.py", line 81, in init_xcpd_wf
    single_subject_wf = init_single_subject_wf(subject_id, anat_session, func_sessions)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/workflows/base.py", line 137, in init_single_subject_wf
    subj_data = collect_data(
                ^^^^^^^^^^^^^
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/utils/bids.py", line 605, in collect_data
    volspace, updated_queries = _select_cifti_volspace(
                                ^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/utils/bids.py", line 375, in _select_cifti_volspace
    raise FileNotFoundError(f'No BOLD NIfTI or transforms found to allowed space ({volspace})')
FileNotFoundError: No BOLD NIfTI or transforms found to allowed space (None)

Screenshots / relevant information:

directory tree of $fmriprep_dir/sub-A00086474

sub-A00086474
├── anat
│   ├── sub-A00086474_desc-brain_mask.json
│   ├── sub-A00086474_desc-brain_mask.nii.gz
│   ├── sub-A00086474_desc-preproc_T1w.json
│   ├── sub-A00086474_desc-preproc_T1w.nii.gz
│   ├── sub-A00086474_space-MNI152NLin6Asym_desc-brain_mask.json
│   └── sub-A00086474_space-MNI152NLin6Asym_desc-brain_mask.nii.gz
├── ses-BAS1
│   ├── anat
│   │   └── sub-A00086474_ses-BAS1_from-orig_to-T1w_mode-image_xfm.txt
│   └── func
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-brain_mask.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-brain_mask.nii.gz
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-confounds_timeseries.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-confounds_timeseries.tsv
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-coreg_boldref.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-coreg_boldref.nii.gz
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-hmc_boldref.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_desc-hmc_boldref.nii.gz
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_from-boldref_to-T1w_mode-image_desc-coreg_xfm.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_from-boldref_to-T1w_mode-image_desc-coreg_xfm.txt
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_from-orig_to-boldref_mode-image_desc-hmc_xfm.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_from-orig_to-boldref_mode-image_desc-hmc_xfm.txt
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-fsLR_den-91k_bold.dtseries.nii
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-fsLR_den-91k_bold.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_boldref.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_boldref.nii.gz
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-brain_mask.json
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-brain_mask.nii.gz
│       ├── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-preproc_bold.json
│       └── sub-A00086474_ses-BAS1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-preproc_bold.nii.gz
├── ses-BAS1-FLU1
│   └── log
│       └── 20260428-094247_1bd3063e-fc0a-472f-ac04-23abd271aa1b
│           └── fmriprep.toml
└── ses-FLU1
    ├── anat
    │   └── sub-A00086474_ses-FLU1_from-orig_to-T1w_mode-image_xfm.txt
    └── func
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-brain_mask.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-brain_mask.nii.gz
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-confounds_timeseries.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-confounds_timeseries.tsv
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-coreg_boldref.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-coreg_boldref.nii.gz
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-hmc_boldref.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_desc-hmc_boldref.nii.gz
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_from-boldref_to-T1w_mode-image_desc-coreg_xfm.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_from-boldref_to-T1w_mode-image_desc-coreg_xfm.txt
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_from-orig_to-boldref_mode-image_desc-hmc_xfm.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_from-orig_to-boldref_mode-image_desc-hmc_xfm.txt
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-fsLR_den-91k_bold.dtseries.nii
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-fsLR_den-91k_bold.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_boldref.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_boldref.nii.gz
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-brain_mask.json
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-brain_mask.nii.gz
        ├── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-preproc_bold.json
        └── sub-A00086474_ses-FLU1_task-rest_acq-1400_space-MNI152NLin6Asym_desc-preproc_bold.nii.gz

Note that i kept only the minimally required inputs

Not sure if this is relevant, but when i added the flag -–session-id BAS1, i got a different error:

A valid FreeSurfer license file is recommended. Set the FS_LICENSE environment variable or use the '--fs-license-file' flag.
The '--skip-parcellation' flag is deprecated and will be removed in a future release. Use '--skip parcellation' instead.
Framewise displacement-based scrubbing is disabled. The following parameters will have no effect:
	--min-time
Traceback (most recent call last):
  File "/app/.pixi/envs/xcp-d/bin/xcp_d", line 10, in <module>
    sys.exit(main())
             ^^^^^^
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/cli/run.py", line 25, in main
    parse_args(args=sys.argv[1:])
  File "/app/.pixi/envs/xcp-d/lib/python3.12/site-packages/xcp_d/cli/parser.py", line 989, in parse_args
    raise ValueError(
ValueError: The configuration hash in the dataset description (98ab3507) does not match the hash in the config (7152476b).
```

Hi @gerardyu,

Looks like there’s no T1w-to-MNI xfm in your subject data. From the documentation you posted, one of the requirements is:

The transform from the native anatomical space to the standard space the BOLD image is in, and its inverse.

Best,

Steven

i see… I can just run fmriprep with the --anat-only flag to get the required xfm right?

Yes, that should work. Could also run the registration yourself with antsRegistration.