Skip to content

Conversation

@StephanPreibisch
Copy link

@StephanPreibisch StephanPreibisch commented Jan 4, 2026

Fixes NullPointerException when writing blocks that are entirely filled with default values. NonEmptyDataBlockSupplier returns null for such blocks as an optimization, but the codec chain didn't handle this properly.

Changes:

  1. DefaultDatasetAccess.writeRegionRecursive(): Add null check before encoding blocks. Return null to signal that empty blocks should not be written.

  2. RawBlockCodecs.encode(): Add defensive null check to prevent NPE when creating LazyReadData with null dataBlock.

This allows N5Utils.saveNonEmptyBlock() to work correctly with Zarr codecs and prevents crashes when writing multi-resolution pyramids with partial blocks containing only default values.

Second commit, Fix: Skip pva.put() for null blocks in writeRegion()

Adds the third and final fix to handle empty blocks from
NonEmptyDataBlockSupplier. After writeRegionRecursive() returns null
for empty blocks, writeRegion() must check for null before calling
pva.put(). Without this check, a NullPointerException occurs at
PositionValueAccess.put() line 113.

Note, this is for ZarrV2 using N5ZarrWriter.

There is an extra issue reading empty blocks from a sharded ZarrV3 dataset, I am right now using N5Utils.saveBlock instead of N5Utils.saveNonEmptyBlock when saving sharded data.

Please note, this code was suggested by Claude that it would fix the issue, I have not thought it through since I am not deeply inside the N5-API. Importantly, a test that reproduces the error is available here: JaneliaSciComp/multiview-reconstruction@4789200

Fixes NullPointerException when writing blocks that are entirely filled
with default values. NonEmptyDataBlockSupplier returns null for such blocks
as an optimization, but the codec chain didn't handle this properly.

Changes:
1. DefaultDatasetAccess.writeRegionRecursive(): Add null check before
   encoding blocks. Return null to signal that empty blocks should not
   be written.

2. RawBlockCodecs.encode(): Add defensive null check to prevent NPE when
   creating LazyReadData with null dataBlock.

This allows N5Utils.saveNonEmptyBlock() to work correctly with Zarr codecs
and prevents crashes when writing multi-resolution pyramids with partial
blocks containing only default values.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
@StephanPreibisch
Copy link
Author

related to this pull request in n5-zarr: saalfeldlab/n5-zarr#85

Adds the third and final fix to handle empty blocks from
NonEmptyDataBlockSupplier. After writeRegionRecursive() returns null
for empty blocks, writeRegion() must check for null before calling
pva.put(). Without this check, a NullPointerException occurs at
PositionValueAccess.put() line 113.

This completes the fix chain:
1. RawBlockCodecs.encode() - return null for null DataBlock
2. DefaultDatasetAccess.writeRegionRecursive() - return null for empty blocks
3. DefaultDatasetAccess.writeRegion() - skip pva.put() for null modifiedData

All tests now pass, including multi-resolution pyramid export with
partial blocks containing only default values.

Also updates copyright year in LICENSE.md to 2026.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
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