# Buggy code
def prepare_variable(self, name, variable, check_encoding=False, unlimited_dims=None):
    attrs = variable.attrs.copy()
    dims = variable.dims
    dtype = variable.dtype
    shape = variable.shape

    fill_value = _ensure_valid_fill_value(attrs.pop("_FillValue", None), dtype)
    if variable.encoding == {"_FillValue": None} and fill_value is None:
        variable.encoding = {}

    encoding = _extract_zarr_variable_encoding(
        variable, raise_on_invalid=check_encoding
    )

    encoded_attrs = OrderedDict()
    # the magic for storing the hidden dimension data
    encoded_attrs[_DIMENSION_KEY] = dims
    for k, v in iteritems(attrs):
        encoded_attrs[k] = self.encode_attribute(v)

    zarr_array = self.ds.create(
        name, shape=shape, dtype=dtype, fill_value=fill_value, **encoding
    )
    zarr_array.attrs.put(encoded_attrs)

    return zarr_array, variable.data


# Traceback (ValueError)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-fff1cd753e7c> in <module>()
2 fs = s3fs.S3FileSystem(anon=False)
3 d = s3fs.S3Map(f_zarr, s3=fs)
----> 4 xr.open_zarr(d)

/opt/conda/lib/python3.6/site-packages/xarray/backends/zarr.py in open_zarr(store, group, synchronizer, auto_chunk, decode_cf, mask_and_scale, decode_times, concat_characters, decode_coords, drop_variables)
476
477         variables = OrderedDict([(k, maybe_chunk(k, v))
--> 478                                  for k, v in ds.variables.items()])
479         return ds._replace_vars_and_dims(variables)
480     else:

/opt/conda/lib/python3.6/site-packages/xarray/backends/zarr.py in <listcomp>(.0)
476
477         variables = OrderedDict([(k, maybe_chunk(k, v))
--> 478                                  for k, v in ds.variables.items()])
479         return ds._replace_vars_and_dims(variables)
480     else:

/opt/conda/lib/python3.6/site-packages/xarray/backends/zarr.py in maybe_chunk(name, var)
471                 token2 = tokenize(name, var._data)
472                 name2 = 'zarr-%s' % token2
--> 473                 return var.chunk(chunks, name=name2, lock=None)
474             else:
475                 return var

/opt/conda/lib/python3.6/site-packages/xarray/core/variable.py in chunk(self, chunks, name, lock)
820             data = indexing.ImplicitToExplicitIndexingAdapter(
821                 data, indexing.OuterIndexer)
--> 822             data = da.from_array(data, chunks, name=name, lock=lock)
823
824         return type(self)(self.dims, data, self._attrs, self._encoding,

/opt/conda/lib/python3.6/site-packages/dask/array/core.py in from_array(x, chunks, name, lock, asarray, fancy, getitem)
1988     >>> a = da.from_array(x, chunks=(1000, 1000), lock=True)  # doctest: +SKIP
1989     """
-> 1990     chunks = normalize_chunks(chunks, x.shape)
1991     if name in (None, True):
1992         token = tokenize(x, chunks)

/opt/conda/lib/python3.6/site-packages/dask/array/core.py in normalize_chunks(chunks, shape)
1918             raise ValueError(
1919                 "Chunks and shape must be of the same length/dimension. "
-> 1920                 "Got chunks=%s, shape=%s" % (chunks, shape))
1921
1922     if shape is not None:

ValueError: Chunks and shape must be of the same length/dimension. Got chunks=(3, 64), shape=(3,)

# Fixed code
def prepare_variable(self, name, variable, check_encoding=False, unlimited_dims=None):
    attrs = variable.attrs.copy()
    dims = variable.dims
    dtype = variable.dtype
    shape = variable.shape

    fill_value = attrs.pop("_FillValue", None)
    if variable.encoding == {"_FillValue": None} and fill_value is None:
        variable.encoding = {}

    encoding = _extract_zarr_variable_encoding(
        variable, raise_on_invalid=check_encoding
    )

    encoded_attrs = OrderedDict()
    # the magic for storing the hidden dimension data
    encoded_attrs[_DIMENSION_KEY] = dims
    for k, v in iteritems(attrs):
        encoded_attrs[k] = self.encode_attribute(v)

    zarr_array = self.ds.create(
        name, shape=shape, dtype=dtype, fill_value=fill_value, **encoding
    )
    zarr_array.attrs.put(encoded_attrs)

    return zarr_array, variable.data