# Buggy code
def fromtiledb(uri, ctx=None, key=None, timestamp=None, gpu=False):
    import tiledb

    raw_ctx = ctx
    if raw_ctx is None:
        ctx = tiledb.Ctx()

    # get metadata from tiledb
    try:
        tiledb_arr = tiledb.DenseArray(uri=uri, ctx=ctx, key=key, timestamp=timestamp)
        sparse = False
    except ValueError:
        # if the array is not dense, ValueError will be raised by tiledb
        tiledb_arr = tiledb.SparseArray(uri=uri, ctx=ctx, key=key, timestamp=timestamp)
        sparse = True

    if tiledb_arr.nattr > 1:
        raise NotImplementedError(
            "Does not supported TileDB array schema with more than 1 attr"
        )
    tiledb_dim_starts = tuple(
        tiledb_arr.domain.dim(j).domain[0] for j in range(tiledb_arr.ndim)
    )
    if any(isinstance(s, float) for s in tiledb_dim_starts):
        raise ValueError(
            "Does not support TileDB array schema whose dimensions has float domain"
        )

    dtype = tiledb_arr.attr(0).dtype
    tiledb_config = None if raw_ctx is None else ctx.config().dict()
    tensor_order = (
        TensorOrder.C_ORDER
        if tiledb_arr.schema.cell_order == "row-major"
        else TensorOrder.F_ORDER
    )
    op = TensorTileDBDataSource(
        tiledb_config=tiledb_config,
        tiledb_uri=uri,
        tiledb_key=key,
        tiledb_timstamp=timestamp,
        tiledb_dim_starts=tiledb_dim_starts,
        gpu=gpu,
        sparse=sparse,
        dtype=dtype,
    )
    chunk_size = tuple(
        int(tiledb_arr.domain.dim(i).tile) for i in range(tiledb_arr.domain.ndim)
    )
    return op(tiledb_arr.shape, chunk_size=chunk_size, order=tensor_order)


# Traceback (AttributeError)
In [3]: import pandas as pd

In [4]: data = pd.DataFrame(np.arange(20).reshape((4, 5)) + 1, columns=['a', 'b', 'c', 'd', 'e'])

In [6]: df = md.DataFrame(data)

In [7]: df.groupby(['a','b']).size().execute()
Unexpected exception occurred in enter_build_mode.<locals>.inner.
Traceback (most recent call last):
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 353, in _wrapped
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 493, in inner
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/scheduler/graph.py", line 633, in prepare_graph
self._target_tileable_datas + fetch_tileables, tileable_graph)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 399, in _wrapped
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 493, in inner
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 350, in build
tileables, tileable_graph=tileable_graph)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 399, in _wrapped
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 493, in inner
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 263, in build
self._on_tile_failure(tileable_data.op, exc_info)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 302, in inner
raise exc_info[1].with_traceback(exc_info[2]) from None
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 243, in build
tiled = self._tile(tileable_data, tileable_graph)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 338, in _tile
return super()._tile(tileable_data, tileable_graph)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 203, in _tile
tds = on_tile(tileable_data.op.outputs, tds)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/scheduler/graph.py", line 615, in on_tile
return self.context.wraps(handler.dispatch)(first.op)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/context.py", line 69, in h
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/utils.py", line 399, in _wrapped
return func(*args, **kwargs)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/tiles.py", line 119, in dispatch
tiled = op_cls.tile(op)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/dataframe/groupby/aggregation.py", line 481, in tile
return cls._tile_with_tree(op)
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/dataframe/groupby/aggregation.py", line 412, in _tile_with_tree
index = out_df.index_value.to_pandas()
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/dataframe/core.py", line 283, in to_pandas
return self._index_value.to_pandas()
File "/Users/hekaisheng/Documents/mars_dev/mars/mars/dataframe/core.py", line 197, in to_pandas
sortorder=self._sortorder, names=self._names)
AttributeError: _sortorder

# Fixed code
def fromtiledb(uri, ctx=None, key=None, timestamp=None, gpu=False):
    import tiledb

    raw_ctx = ctx
    if raw_ctx is None:
        ctx = tiledb.Ctx()

    # get metadata from tiledb
    try:
        tiledb_arr = tiledb.DenseArray(uri=uri, ctx=ctx, key=key, timestamp=timestamp)
        sparse = False
    except ValueError:
        # if the array is not dense, ValueError will be raised by tiledb
        tiledb_arr = tiledb.SparseArray(uri=uri, ctx=ctx, key=key, timestamp=timestamp)
        sparse = True

    if tiledb_arr.nattr > 1:
        raise NotImplementedError(
            "Does not supported TileDB array schema with more than 1 attr"
        )
    tiledb_dim_starts = tuple(
        tiledb_arr.domain.dim(j).domain[0].item() for j in range(tiledb_arr.ndim)
    )
    if any(isinstance(s, float) for s in tiledb_dim_starts):
        raise ValueError(
            "Does not support TileDB array schema whose dimensions has float domain"
        )

    dtype = tiledb_arr.attr(0).dtype
    tiledb_config = None if raw_ctx is None else ctx.config().dict()
    tensor_order = (
        TensorOrder.C_ORDER
        if tiledb_arr.schema.cell_order == "row-major"
        else TensorOrder.F_ORDER
    )
    op = TensorTileDBDataSource(
        tiledb_config=tiledb_config,
        tiledb_uri=uri,
        tiledb_key=key,
        tiledb_timstamp=timestamp,
        tiledb_dim_starts=tiledb_dim_starts,
        gpu=gpu,
        sparse=sparse,
        dtype=dtype,
    )
    chunk_size = tuple(
        int(tiledb_arr.domain.dim(i).tile) for i in range(tiledb_arr.domain.ndim)
    )
    return op(tiledb_arr.shape, chunk_size=chunk_size, order=tensor_order)