# Changelog

<!-- scriv-insert-here -->

<a id='changelog-3.0.0'></a>
# 3.0.0 — 2026-07-13

This is a major release that includes breaking changes to the public API.
The CLI remains unchanged, but library users should review the changes below
and update their code accordingly.

The primary user-facing changes in this release are the support for
validating git trees and passing custom schemas to the web validator.

Thanks to Charan Sai Guttala, Yaroslav Halchenko, Dimitri Papadopoulos,
Kay Robbins and Chris Rorden for their contributions to this release.

## Added

- `--git-ref [REF]` will validate a git tree at the given reference
  (tag, branch, tree or commit, defaulting to `HEAD`). Work trees and bare git
  repositories are supported. If omitted, the directory will be walked as a normal
  file tree, including untracked files, preserving the default behavior.

- Allow custom schemas to be uploaded or passed by URL to the web validator.

- Support symlinks to directories in git tree validation.

- Report broken symbolic links as issues instead of crashing or silently ignoring.
  `.bidsignore`d links are not reported. If resolution is not implemented, warnings
  are issued instead of errors.

- Documented the library API: added a usage guide under `docs/dev/using-the-api.md`,
  JSDoc on `validate()`, and JSDoc with `@throws` on `DatasetIssues.add()`.

- New public subpaths expose primitives for building custom file sources:
  `FileOpener`, `BIDSFile`, `FileTree`, `FileIgnoreRules`, `filesToTree`,
  `subtree`, `loadBidsIgnore`, `readBidsIgnore`, and cross-environment openers
  (`HTTPOpener`, `NullFileOpener`).

- `detectErrors()` is now part of the public surface under `/validate`.

- `UnknownIssueCodeError` — `DatasetIssues.add()` now throws a typed error
  (instead of a plain `Error`) when called with an unrecognized issue code.

- Stream helpers (`createUTF8Stream`, `streamFromUint8Array`, `streamFromString`,
  `UnicodeDecodeError`) exported from `/files` for custom opener authors.

## Changed

- Reorganized public API surface for v3. Library imports now use subpath-specific
  entry points (`/validate`, `/files`, `/filetree`, `/files/deno`, `/files/browser`,
  `/files/git`, `/issues`, `/output`, `/cli`). The root export (`.`) remains the
  CLI entry point.

- The `--prune` option removes opaque BIDS directories (`sourcedata/`, `derivatives/`, etc.)
  from the file tree, reducing processing time and memory usage.
  This option is incompatible with recursive validation and may cause unexpected
  behavior if pruned data are referenced by name or via symbolic links.

## Fixed

- Test suite now passes on Windows: `src/tests/bom-utf8.json`
  is pinned to LF line endings via `.gitattributes`
  (previously checked out as CRLF, breaking the
  BOM-stripping assertion).

- `chmod -R +w` cleanup calls in`src/files/git.test.ts` and
  `src/files/utils.test.ts` are skipped on Windows
  where `chmod` is not available.

- Use absolute path to `.js` within Dockerfile ENTRYPOINT,
  so could be found by singularity execution from arbitrary
  working directory

- Treat symbolic links to directories as directories instead of files.

- Compute opaque directories from the rules for the dataset's actual
  `DatasetType` instead of always using `rules.directories.raw`.  This
  lets study-type datasets correctly ignore the `rawbids/`
  subdataset (added in [bids-standard/bids-specification#2191][]).
  Fixed in [#389][].

- Derivative datasets no longer generate warnings or errors for sidecar keys that don't explicitly apply to derivative datasets.

- Lazy-load the HED validator to reduce initial bundle size and resolve `fs/promises` background timer leaks during Deno tests.

- Debug logging is fixed for WebKit-based runners, such as Safari or Tauri.
  Issue reported by Chris Rorden in [#405][].

- Fixed `useEffect` in `web/src/App.tsx` returning a Promise instead of a void
  cleanup function, causing React strict mode to throw
  `TypeError: destroy is not a function`.

- Fixed duplicate React `key` warning in the web validator `Files` component:
  the `<li>` key was `location` alone, but two issues at the same path with
  different `issueMessage` values both survive deduplication and then collide.
  The key now uses the composite `${location}${issueMessage}` string that
  matches the deduplication map key.

- Replaced `canvas-confetti` CDN import (jsdelivr) in `web/src/App.tsx` with an
  `npm:` specifier so the build no longer requires outbound HTTP access to
  jsdelivr.net; added the corresponding pre-import in `web/vite.config.mts`.

- `.dotfiles` and directories (such as `.git/`) are now pruned from the file tree,
  avoiding unnecessary IO operations and memory consumption.

[bids-standard/bids-specification#2191]: https://github.com/bids-standard/bids-specification/pull/2191
[#389]: https://github.com/bids-standard/bids-validator/pull/389
[#405]: https://github.com/bids-standard/bids-validator/pull/405


## Deprecated

- `@bids/validator/main` — use `/validate`, `/files/browser`, `/files/git` instead.
  `main()` is preserved for back-compat; it has no replacement and will be removed
  in v4.
- `@bids/validator/options` — use `/validate` (types) and `/cli` (validateCommand)
  instead. `parseOptions()` is preserved for back-compat; it has no replacement and
  will be removed in v4.
- `readFileTree` and `BIDSFileDeno` re-exported from `/files` — use `/files/deno`
  instead.

## Infrastructure

- Addressed or ignored all `deno lint` issues. Future work should lint clean.

- Added a developer environment guide under `docs/dev/environment.md`.

- The `main.js` build target has been renamed `web.js` for clarity.
  It will no longer be saved to the `deno-build` branch.

- Code-splitting was enabled in bundle configuration to make the validator more
  friendly to load in the browser or include in downstream bundled applications.
  The initial validator load transfers less than 400kB and
  only loads an additional 1.2MB if HED validation is required.

- Upgraded `@hed/validator` from `~4.1.4` to `^4.2.0` in `deno.json`; moved
  `pluralize` from a transitive hed-validator dependency to a direct import now
  that hed-validator is published on npm without bundling it.

- Added a CI job that installs the built wheel on each OS/arch and validates the
  bids-examples corpus via its `run_tests.sh`, guarding wheel packaging changes.

- PyPI wheels now set a minimum Python of 3.10.

- The `bids-validator-deno` wheel is now a single universal (`py3-none-any`)
  package that depends on the `deno` PyPI package, reducing overhead of supporting
  multiple platforms.

<a id='changelog-2.4.1'></a>
# 2.4.1 — 2026-02-20

## Changed

- Update to BIDS Schema v1.2.1 (BIDS v1.11.1)

- The web validator now renders Markdown in issue messages.

## Fixed

- Validating directory names is now skipped for unknown `DatasetType`s in
  `dataset_description.json`. Previously this would crash, preventing the error
  in `DatasetType` values from being reported to the user.

## Infrastructure

- Added a [pre-commit](https://pre-commit.com/) configuration for developers.
  To enable, run `pre-commit install`. For speed, we recommend installing `pre-commit`
  via `uv tool install pre-commit --with=pre-commit-uv`.

<a id='changelog-2.4.0'></a>
# 2.4.0 — 2026-02-05

## Changed

- Update to BIDS Schema v1.2.0 (BIDS v1.11.0)

<a id='changelog-2.3.2'></a>
# 2.3.2 — 2026-02-02

## Changed

- File reads are temporarily cached to avoid multiple fetches/opens.

## Fixed

- Retrieval of remote data on S3 is now more robust, avoiding resource leaks
  by setting timeouts and a reasonable retry protocol.

<a id='changelog-2.3.1'></a>
# 2.3.1 — 2026-01-27

Mismatch between version and tag. Re-releasing for consistency. No other changes.

<a id='changelog-2.3.0'></a>
# 2.3.0 — 2026-01-27

## Changed

- Improve types for memoized functions by passing argument and return types to callers.

- Render Markdown links as OSC-8 links in terminals where support is detected.

## Fixed

- Exit with a non-zero exit code if nested datasets are validated and found to have errors.

- Prevent HED check from failing for null values found in sidecar metadata.

<a id='changelog-2.2.10'></a>
# 2.2.10 — 2026-01-15

## Changed

- Improve types for memoized functions by passing argument and return types to callers.

## Fixed

- Extract AWS region from S3 special remote, defaulting to us-east-1.

<a id='changelog-2.2.9'></a>
# 2.2.9 — 2026-01-15

## Changed

- Reverted terminal URLs for the 2.2.x series. It should be back in 2.3.0.

<a id='changelog-2.2.8'></a>
# 2.2.8 — 2026-01-15

## Changed

- Render Markdown links as OSC-8 links in terminals where support is detected.

## Fixed

- Fix typo in S3 URL generation code that prevented reading remote files.

<a id='changelog-2.2.7'></a>
# 2.2.7 — 2026-01-13

## Added

- Maintainer documentation for creating and fixing releases.

- Support for rendering Markdown in validation messages in the terminal.

- Display validation summaries for derivative datasets when recursive validation
  (`-r`/`--recursive`) is run.

- Support for presigning S3 URLs if AWS credentials are detected.

## Fixed

- Validate derivative file paths relative to the derivative dataset root.

- Have all three calls to fetch in HttpOpener use same error handling.

- Fix memoization memory leak for readRemotes.

- Replace SPEC_ROOT placeholder with actual documentation link in CLI output

## Infrastructure

- Pin Deno to 2.5.6 in wheel builds to account for bugs with MacOS binaries compiled with 2.6.0.

<a id='changelog-2.2.5'></a>
# 2.2.5 — 2025-12-10

## Added

- Support for template and cohort directories, as introduced in BEP038.

## Fixed

- The AMBIGUOUS_AFFINE issue was given an error message and set to warning.

- Very oblique affines are no longer considered ambiguous.

- Resolved TypeError when rendering issues for JSON outputs.

<a id='changelog-2.2.4'></a>
# 2.2.4 — 2025-12-05

## Added

- Annexed files with base-64-encoded version information are now supported.

<a id='changelog-2.2.3'></a>
# 2.2.3 — 2025-11-25

## Fixed

- NIfTI files with bad qform matrices, resulting from non-normalized quaternions,
  would previously raise a NIFTI_HEADER_UNREADABLE error. Now only the axis codes
  are disabled, preventing orientation checks, but not raising errors.

<a id='changelog-2.2.2'></a>
# 2.2.2 — 2025-11-12

## Changed

- Support `min()` and `max()` of numbers in the expression language.
  This allows for simpler rules when a field may be a number or array of numbers.

- [Annexed](https://git-annex.branchable.com/) files that are not local are treated as
  empty instead of erroring if a remote URL could not be constructed. The size of missing
  files are included in the summary estimate of dataset size.

## Fixed

- `INVALID_FILE_ENCODING` issues now print sensible messages instead of crashing.

<a id='changelog-2.2.1'></a>
# 2.2.1 — 2025-10-27

## Added

- Support for `associations.physio` and `associations.events.sidecar`.

- Implement `associations.coordsystems` to collate multiple `coordsystem.json` files,
  as required by BEP 042 (EMG).

## Changed

- Validation context generation was tweaked to improve concurrency, giving 4x validation
  speedups in some cases.

<a id='changelog-2.2.0'></a>
# 2.2.0 — 2025-10-14

## Added

- Added `--format` option to specify output format: `text` (default), `json`, or `json_pp` (pretty-printed JSON)
- Pretty-printed JSON output support via `--format json_pp` option

- Datalad/git-annex datasets with remote content in public S3 buckets can be validated
  with the `--preferredRemote <remote-name>` flag. If a public S3 bucket is detected without
  this flag, the most recent export is used.

## Changed

- Refactored file access classes to be more DRY.

## Fixed

- Circular references that could lead to a hanging process were mitigated. [#278]

[#278]: https://github.com/bids-standard/bids-validator/issues/278

## Deprecated

- Deprecated `--json` option in favor of `--format json` (backward compatibility maintained)

<a id='changelog-2.1.1'></a>
# 2.1.1 — 2025-09-26

## Added

- Additional (dataset-defined) columns are now validated against the
  definitions in the sidecar files.

- Throw error on file name case collision.

- Add support for the `unique()` function in schema expressions.

- Support issues messages that access validation context variables.

## Changed

- Initial column TSV checks now support missing, optional initial columns.

- Index column TSV checks now support missing, optional index columns.

- Now supports Deno 2.5 and Typescript 5.9.2.

- Parsed JSON files are now cached to reduce I/O and parsing costs.

- Throw an error if specified schema (e.g. via `--schema` or `BIDS_SCHEMA` env
  var) could not be loaded.

## Fixed

- File access failures consistently produce `FILE_READ` errors across all file types.

- Fixed json encoding issue in web log download ([#174]).

- Throw utf-8 encoding error for tsv files similar to json files.

[#174]: https://github.com/bids-standard/bids-validator/issues/174

<a id='changelog-2.1.0'></a>
# 2.1.0 — 2025-09-03

This release adds support for BIDS 1.10.1.

## Added

- Load `.tsv.gz` column contents for validation.

- Issue deprecation warning for `"89+"` in `age` columns, per
  [bids-standard/bids-specification#2162][].

- Added support for extracting image orientation from NIfTI headers,
  added to the BIDS schema in 1.10.1.

## Changed

- Raise errors for all TSV type check failures.
  Previously, recommended and optional fields would raise warnings.

- Updated `@bids/schema` to ~1.1.0, corresponding to BIDS version 1.10.1.

## Fixed

- Avoid descending into opaque directories (such as `*.zarr/`) when checking
  for unused sidecars. ([#227])

[#227]: https://github.com/bids-standard/bids-validator/issues/227
[bids-standard/bids-specification#2162]: https://github.com/bids-standard/bids-specification/pull/2162

<a id='changelog-2.0.11'></a>
# 2.0.11 — 2025-08-29

## Fixed

- Docker build workflow should now run correctly on releases.

<a id='changelog-2.0.10'></a>
# 2.0.10 — 2025-08-29

## Added

- Added a [FAQ] to the user guide. ([#215])

[FAQ]: https://bids-validator.readthedocs.io/en/latest/user_guide/faq.html
[#215]: https://github.com/bids-standard/bids-validator/issues/215

## Changed

- Improved handling of TSV columns with sidecar definitions.
  `"Format"`, `"Minimum"` and `"Maximum"` keys are now supported.

- `--datasetTypes` and `--blacklistModalities` options now accept a string array (`--datasetTypes raw,derivative`) and can be combined.

## Fixed

- A crash in the web validator prevented validation from taking place.

## Infrastructure

- Docker images will once again be pushed to [bids/validator][].

[bids/validator]: https://hub.docker.com/r/bids/validator/

<a id='changelog-2.0.9'></a>
# 2.0.9 — 2025-08-26

## Added

- Display version in web app

- The `--datasetTypes` flag accepts a list of `DatasetType`s,
  allowing applications to restrict the datasets they accept.

## Changed

- Upgraded to BIDS schema version 1.0.13.

- Raise error when JSON files are parsed and their root value is anything other than an object

<a id='changelog-2.0.8'></a>
# 2.0.8 — 2025-08-07

## Added

- Support multi-inheritance for associated files.
  This will allow for multiple `electrodes.tsv` files,
  distinguished by the `space-` entity. ([#206] [#207])

[#206]: https://github.com/bids-standard/bids-validator/issues/206
[#207]: https://github.com/bids-standard/bids-validator/pull/207

<a id='changelog-2.0.7'></a>
# 2.0.7 — 2025-06-03

## Changed

- Handle TSV schema rules with missing or `n/a` values for `additional_columns`.

<a id='changelog-2.0.6'></a>
# 2.0.6 — 2025-05-23

## Added

- Explain the issue data fields in the documentation. ([#199])

[#199]: https://github.com/bids-standard/bids-validator/pull/199

## Changed

- Validator now returns exit code 16 instead of 1 for validation of a dataset with errors.

- Rely on `schema.meta.associations` to load context associations instead of relying on list maintained in validator.

## Fixed

- Sidecar checks are skipped for text files that should not have sidecars.
  This resolves a problem in derivative datasets, where BIDS specifies a
  RECOMMENDED field of `Description` in all derivative files. ([#202])

[#202]: https://github.com/bids-standard/bids-validator/issues/202
<a id='changelog-2.0.4'></a>
# 2.0.5 — 2025-03-31

A hot-fix release that adds missing entries to the 2.0.4 changelog and fixes publication to PyPI.

<a id='changelog-2.0.4'></a>
# 2.0.4 — 2025-03-31

## Added

- Validate directory names names according to `schema.rules.directories` entries.
  Use rules to identify "opaque" directories whose contents are unspecified by BIDS.
  ([#180])

[#180]: https://github.com/bids-standard/bids-validator/pull/180

- Report field descriptions for missing or invalid metadata. ([#177])

[#177]: https://github.com/bids-standard/bids-validator/pull/177

- Publish validator to PyPI as `bids-validator-deno`. ([#186])

[#186]: https://github.com/bids-standard/bids-validator/pull/186

## Changed

- Update to HED Validator 4.0.0. ([#173])

[#173]: https://github.com/bids-standard/bids-validator/pull/173

<a id='changelog-2.0.3'></a>
# 2.0.3 — 2025-02-24

## Fixed

- Subject detection in `participants.tsv` and `phenotype/` directories
  has been restored, enabling checks that were deactivated by the missing
  data. ([#162])

[#162]: https://github.com/bids-standard/bids-validator/pull/162

- Skip HED tests if schema cannot be loaded. This was exhibiting
  as a `HED_ERROR` with "cannot read property null". ([#160])

[#160]: https://github.com/bids-standard/bids-validator/pull/160

- `TSV_INCORRECT_VALUE_TYPE*` error messages now indicate that a match
  failed, instead of confusingly claim success. ([#165])

[#165]: https://github.com/bids-standard/bids-validator/pull/165

<a id='changelog-2.0.2'></a>
# 2.0.2 — 2025-02-10

## Added

- Enable glob-style wildcards for `location` field in configuration files. (#134)

## Changed

- Ensure HED schemas are loaded only once, improving efficiency. (#156)

- Change the output of the `intersects()` function in the expression language
  to return the intersection, if non-empty.
  Corresponds to [bids-standard/bids-specification#2044]. (#150)

- Update to BIDS schema version 1.0.1 (BIDSVersion 1.10.0) (#152)

- Limit TSV validation to first 1000 rows by default,
  adding the `--max-rows` flag to control this behavior. (#139)

[bids-standard/bids-specification#2044]: https://github.com/bids-standard/bids-specification/pull/2044

## Fixed

- TSV files may now have columns named `set`, `clear`, `delete`, `keys`, or `value`.
  These were previously masked by the methods on the data structure
  representing columns. (#155)

- Improve handling of `.bidsignore` files in the web validator.
  Ignores matching directories but not the files they contained could fail to match.
  (#113)

- Resolve issue with parsing headers of NIfTI files with large extensions.
  Fixes [issue 126].

[issue 126]: https://github.com/bids-standard/bids-validator/issues/126

## Infrastructure

- Adopting [scriv](https://scriv.readthedocs.io/en/latest/) for changelog
  management.

<a id='changelog-2.0.1'></a>
# 2.0.1 — 2024-12-10

## Fixed

- Improve handling of `.bidsignore` files in the web validator.
  Ignores matching directories but not the files they contained could fail to match.
  (#113)

- Resolve issue with parsing headers of NIfTI files with large extensions.
  Fixes [issue 126].

[issue 126]: https://github.com/bids-standard/bids-validator/issues/126

## Infrastructure

- Adopting [scriv](https://scriv.readthedocs.io/en/latest/) for changelog
  management.
