Skip to content

to_geotiff writes invalid TIFF for zero-height/zero-width arrays instead of failing closed #2075

@brendancol

Description

@brendancol

Describe the bug

to_geotiff accepts arrays whose spatial height or width is zero. It writes a TIFF file, and the reader then refuses to open it with "Invalid image dimensions". Clip and window pipelines can produce empty rasters, so this turns a recoverable input-validation error into a stale-file-on-disk failure that only surfaces at read time.

The eager validation at xrspatial/geotiff/_writers/eager.py:670 checks arr.ndim but never that height and width are positive. The streaming path at xrspatial/geotiff/_writer.py:1939 then computes zero tile/strip counts and writes a file with no pixel data.

Reproducer

import numpy as np
import xarray as xr
from xrspatial.geotiff import to_geotiff, open_geotiff

for shape in [(0, 5), (5, 0), (0, 0)]:
    da = xr.DataArray(np.zeros(shape, dtype=np.float32), dims=('y', 'x'))
    to_geotiff(da, f'/tmp/empty_{shape[0]}x{shape[1]}.tif')  # succeeds
    open_geotiff(f'/tmp/empty_{shape[0]}x{shape[1]}.tif')    # raises "Invalid image dimensions"

Expected behavior

to_geotiff raises ValueError at the write entry point with a message that names the offending dimension (e.g. "got shape (0, 5) with height=0"). The failure happens before any bytes hit disk.

Actual behavior

The writer produces a file. The error surfaces later at read time with a generic "Invalid image dimensions" message that does not name the writer as the source.

Source locations

  • Eager entry: xrspatial/geotiff/_writers/eager.py:670 (the arr.ndim not in (2, 3) check).
  • Streaming entry: xrspatial/geotiff/_writer.py:1939 (tile/strip count math runs on height/width).

Additional context

Affects all four backends (numpy, cupy, dask+numpy, dask+cupy). The validation gap is upstream of backend dispatch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginput-validationInput validation and error messages

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions