BIDS Migration Guide

This guide covers every upgrade path: from the original bids2nf Nextflow subworkflow, through the early plugin betas, up to 0.3.0.

Version timeline

Version Approx date Key changes Breaking?

Baseline bids2nf

pre-2024

Original Nextflow subworkflow

0.1.0

~Dec 2024

Initial plugin implementation

No

0.1.0-beta.1–4

Early 2025

Core functionality stabilisation

Minor

0.1.0-beta.5

~Oct 2025

java.nio.file.Path objects

Yes

0.1.0-beta.6

~Nov 2025

Flat output format (opt-in); suffix mapping fix

Optional

0.1.0-beta.9

Dec 2025

Flat output becomes the default

Yes

v0.2.0

Future

Legacy tuple format removed

Yes

Identify your starting version

// Baseline bids2nf?
include { bids2nf } from './modules/bids2nf'   // → baseline

// Plugin?
plugins { id 'nf-bids@0.1.0-beta.9' }          // → check version

Run nextflow plugin list to see what is actually loaded.

Migration paths

Path 1: Baseline bids2nf → 0.3.0

Step 1 — Install the plugin

nextflow.config
plugins {
    id 'nf-bids@{plugin-version}'
}

Step 2 — Update the workflow import

// Before
include { bids2nf } from './modules/bids2nf'
workflow { bids_channel = bids2nf(params.bids_dir, 'config.yaml') }

// After
include { fromBIDS } from 'plugin/nf-bids'
workflow { bids_channel = Channel.fromBIDS(params.bids_dir, 'config.yaml') }

Step 3 — Update entity and file access

Old baseline tuple structure
[
    ["sub-01", "ses-01", "NA", "NA"],    // [subject, session, run, task]
    [
        bidsParentDir: "/path/to/bids",
        subject: "sub-01",
        data: [
            dwi: [nii: "sub-01/ses-01/dwi/sub-01_ses-01_dwi.nii.gz"]  // RELATIVE
        ]
    ]
]
// Access: file("${data.bidsParentDir}/${data.data.dwi.nii}")
New flat map structure (beta.9+)
[
    meta: [subject: "sub-01", session: "ses-01", run: "NA"],
    dwi: [
        nii:  Path("/path/to/bids/sub-01/ses-01/dwi/sub-01_ses-01_dwi.nii.gz"),  // ABSOLUTE
        bval: Path("...bval"),
        bvec: Path("...bvec")
    ]
]
// Access: item.dwi.nii  (Path object, no concatenation needed)

Key differences:

  • No outer tuple; items are flat maps.

  • Entity metadata lives in item.meta.*.

  • Paths are absolute java.nio.file.Path objects.

  • Config key names appear directly (e.g. item.dwi, not item.data.dwi).

Step 4 — Common code patterns

// Old: decompose tuple, build path
bids_channel.map { key, data ->
    def sub  = key[0]
    def nii  = file("${data.bidsParentDir}/${data.data.dwi.nii}")
    [sub, nii]
}

// New: direct access
bids_channel.map { item ->
    [item.meta.subject, item.dwi.nii]
}

Path 2: Plugin beta.1–5 → 0.3.0

The primary change is the flat output format becoming default. Add flatten_output: false as a temporary bridge while updating downstream code:

Channel.fromBIDS(params.bids_dir, 'config.yaml', [flatten_output: false])

Then migrate map accesses following the patterns in Path 1 Step 4 and remove the option.

Path 3: beta.6–8 with flatten_output: false → 0.3.0

Remove the flatten_output: false option and update map accesses. The only change is that the flat format is now the default; you no longer need to opt in.

Path 4: beta.6–8 with flatten_output: true (already flat) → 0.3.0

No action required. The flat format is now the default.

Breaking changes by version

0.1.0-beta.9 — Flat output becomes default

Config change
// beta.6–8 to opt INTO flat format:
Channel.fromBIDS(dir, config, [flatten_output: true])

// beta.9+: flat is default, no option needed:
Channel.fromBIDS(dir, config)
// Use [flatten_output: false] to keep legacy format temporarily

0.1.0-beta.5 — Path object transition

All file paths switched to java.nio.file.Path. String paths from earlier versions no longer work directly as Nextflow process inputs.

Troubleshooting

"Reserved key 'meta'" error

BidsConfigLoader rejects configs that use meta as a suffix name. Rename the suffix in your YAML:

# ❌ Rejected
meta:
  plain_set: {}

# ✅ Renamed
subject_metadata:
  plain_set: {}
  suffix_maps_to: meta

Null items in channel

Items are dropped when a required group is missing for named_set or mixed_set. Check your config’s required list against the actual entity values present in your dataset.

libBIDS.sh not found

Ensure the plugin’s embedded libBIDS.sh is available (no action needed for registry installs), or provide an explicit path:

Channel.fromBIDS(dir, config, [libbids_sh: '/path/to/libBIDS.sh'])

Absolute path expected

If downstream code calls file(item.dwi.nii) but item.dwi.nii is already a Path, just use it directly:

process MY_PROCESS {
    input: path nii_file
    ...
}
workflow {
    Channel.fromBIDS(dir, config).map { it.dwi.nii } | MY_PROCESS
}