Skip to content

fix: reject reserved node names on creation - #4484

Open
barlowa124 wants to merge 2 commits into
zarr-developers:mainfrom
barlowa124:reserved-node-names-4453
Open

barlowa124 wants to merge 2 commits into
zarr-developers:mainfrom
barlowa124:reserved-node-names-4453

Conversation

@barlowa124

@barlowa124 barlowa124 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Covers item 1 of #4453. The spec reserves node names beginning with
__ and the name zarr.json, yet creation accepted both:
create_group("__a") wrote the reserved name outright, and
create_group("a/zarr.json") produced a/zarr.json/zarr.json. That
directory shadows the group's own metadata document and leaves the
subtree unreachable through members().

A _validate_node_name helper in zarr.core.common rejects any
/ segment that is zarr.json, __-prefixed, . or .., raising
MetadataValidationError before anything is stored. It runs inside
AsyncGroup.create_group, AsyncGroup.create_array and the
module-level create_array/create_group name/path arguments, so the
require_* and sync wrappers are covered through delegation.

Two boundaries are deliberate: empty segments still pass through
(store_path / has always normalized leading and repeated slashes),
and the open_* read paths are untouched so existing stores holding
such names still open. create_nodes keeps its documented
caller-responsibility contract.

For reviewers

Worth a second look. Whether open_group/open_array in create
modes should share the check is open (mode "a" is also a read mode,
so it would block opening stores that already contain such nodes).
Whether rejecting ./.. segments is welcome is open too, as is
whether the check belongs in Zarr format 2 at all, where zarr.json
is not a metadata name though a directory so named still orphans its
parent. The check is one
loop and narrows easily. Locally each rejected name raised before any
write and members() stayed consistent. tests/test_group.py is
green including the leading-slash parametrization.

Author attestation

  • I am a human. These are my changes. I have reviewed and understood every change and can explain why each is correct.

TODO

Done:

  • Add unit tests and/or doctests in docstrings
  • Add docstrings and API docs for any new/modified user-facing classes and functions
  • New/modified features documented in docs/user-guide/*.md
  • Changes documented as a new file in changes/

CI:

  • GitHub Actions have all passed
  • Test coverage is 100% (Codecov passes)

The Zarr format reserves node names beginning with '__' and the name
'zarr.json'. create_group('__a') wrote the reserved name, and
create_group('a/zarr.json') wrote a directory that shadows the parent's
metadata document, orphaning the whole subtree from members(). Both are
now refused with MetadataValidationError before anything is stored.

The check validates each '/'-separated segment in AsyncGroup.create_group,
AsyncGroup.create_array, and the module-level create_array/create_group
'name'/'path' arguments. Empty segments pass through because leading and
repeated slashes have long been normalized away by path joining.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@github-actions github-actions Bot added the needs release notes Automatically applied to PRs which haven't added release notes label Oct 7, 2026
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@github-actions github-actions Bot removed the needs release notes Automatically applied to PRs which haven't added release notes label Oct 7, 2026
@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.69%. Comparing base (069fd20) to head (7d90be3).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4484   +/-   ##
=======================================
  Coverage   94.69%   94.69%           
=======================================
  Files          94       94           
  Lines       13606    13617   +11     
=======================================
+ Hits        12884    12895   +11     
  Misses        722      722           
Files with missing lines Coverage Δ
src/zarr/api/asynchronous.py 96.49% <100.00%> (+0.02%) ⬆️
src/zarr/core/array.py 98.39% <100.00%> (+<0.01%) ⬆️
src/zarr/core/common.py 92.55% <100.00%> (+0.20%) ⬆️
src/zarr/core/group.py 95.68% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant