# Buggy code
def list_(properties="size,alloc,free,cap,frag,health", zpool=None, parsable=True):
    """
    .. versionadded:: 2015.5.0

    Return information about (all) storage pools

    zpool : string
        optional name of storage pool

    properties : string
        comma-separated list of properties to list

    parsable : boolean
        display numbers in parsable (exact) values

        .. versionadded:: 2018.3.0

    .. note::

        The ``name`` property will always be included, while the ``frag``
        property will get removed if not available

    zpool : string
        optional zpool

    .. note::

        Multiple storage pool can be provded as a space separated list

    CLI Example:

    .. code-block:: bash

        salt '*' zpool.list
        salt '*' zpool.list zpool=tank
        salt '*' zpool.list 'size,free'
        salt '*' zpool.list 'size,free' tank

    """
    ret = OrderedDict()

    ## update properties
    # NOTE: properties should be a list
    if not isinstance(properties, list):
        properties = properties.split(",")

    # NOTE: name should be first property
    while "name" in properties:
        properties.remove("name")
    properties.insert(0, "name")

    # NOTE: remove 'frags' if we don't have feature flags
    if not __utils__["zfs.has_feature_flags"]():
        while "frag" in properties:
            properties.remove("frag")

    ## collect list output
    res = __salt__["cmd.run_all"](
        __utils__["zfs.zpool_command"](
            command="list",
            flags=["-H", "-p"],
            opts={"-o": ",".join(properties)},
            target=zpool,
        ),
        python_shell=False,
    )

    if res["retcode"] != 0:
        return __utils__["zfs.parse_command_result"](res)

    # NOTE: command output for reference
    # ========================================================================
    # data  1992864825344   695955501056    1296909324288   34  11%     ONLINE
    # =========================================================================

    ## parse list output
    for line in res["stdout"].splitlines():
        # NOTE: transform data into dict
        zpool_data = OrderedDict(
            list(
                zip(
                    properties,
                    line.strip().split("\t"),
                )
            )
        )

        # NOTE: normalize values
        if parsable:
            # NOTE: raw numbers and pythonic types
            zpool_data = __utils__["zfs.from_auto_dict"](zpool_data)
        else:
            # NOTE: human readable zfs types
            zpool_data = __utils__["zfs.to_auto_dict"](zpool_data)

        ret[zpool_data["name"]] = zpool_data
        del ret[zpool_data["name"]]["name"]

    return ret


# Traceback (IndexError)
# salt-call saltutil.sync_all
[ERROR   ] Command '/sbin/zpool list -H -p -o name,size' failed with return code: 2
[ERROR   ] output: invalid option 'p'
usage:
list [-gHLPv] [-o property[,...]] [-T d|u] [pool] ... [interval [count]]
...

[CRITICAL] Failed to load grains defined in grain file zfs.zfs in function <function zfs at 0x7fa3241bf2a8>, error:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 756, in grains
ret = funcs[key]()
File "/usr/lib/python2.7/dist-packages/salt/grains/zfs.py", line 116, in zfs
grains = salt.utils.dictupdate.update(grains, _zfs_pool_data(), merge_lists=True)
File "/usr/lib/python2.7/dist-packages/salt/grains/zfs.py", line 102, in _zfs_pool_data
grains['zpool'][zpool[0]] = _conform_value(zpool[1], True)
IndexError: list index out of range
...

# Fixed code
def list_(properties="size,alloc,free,cap,frag,health", zpool=None, parsable=True):
    """
    .. versionadded:: 2015.5.0

    Return information about (all) storage pools

    zpool : string
        optional name of storage pool

    properties : string
        comma-separated list of properties to list

    parsable : boolean
        display numbers in parsable (exact) values

        .. versionadded:: 2018.3.0

    .. note::

        The ``name`` property will always be included, while the ``frag``
        property will get removed if not available

    zpool : string
        optional zpool

    .. note::

        Multiple storage pool can be provded as a space separated list

    CLI Example:

    .. code-block:: bash

        salt '*' zpool.list
        salt '*' zpool.list zpool=tank
        salt '*' zpool.list 'size,free'
        salt '*' zpool.list 'size,free' tank

    """
    ret = OrderedDict()

    ## update properties
    # NOTE: properties should be a list
    if not isinstance(properties, list):
        properties = properties.split(",")

    # NOTE: name should be first property
    while "name" in properties:
        properties.remove("name")
    properties.insert(0, "name")

    # NOTE: remove 'frags' if we don't have feature flags
    if not __utils__["zfs.has_feature_flags"]():
        while "frag" in properties:
            properties.remove("frag")

    ## collect list output
    res = __salt__["cmd.run_all"](
        __utils__["zfs.zpool_command"](
            command="list",
            flags=["-H"],
            opts={"-o": ",".join(properties)},
            target=zpool,
        ),
        python_shell=False,
    )

    if res["retcode"] != 0:
        return __utils__["zfs.parse_command_result"](res)

    # NOTE: command output for reference
    # ========================================================================
    # data  1992864825344   695955501056    1296909324288   34  11%     ONLINE
    # =========================================================================

    ## parse list output
    for line in res["stdout"].splitlines():
        # NOTE: transform data into dict
        zpool_data = OrderedDict(
            list(
                zip(
                    properties,
                    line.strip().split("\t"),
                )
            )
        )

        # NOTE: normalize values
        if parsable:
            # NOTE: raw numbers and pythonic types
            zpool_data = __utils__["zfs.from_auto_dict"](zpool_data)
        else:
            # NOTE: human readable zfs types
            zpool_data = __utils__["zfs.to_auto_dict"](zpool_data)

        ret[zpool_data["name"]] = zpool_data
        del ret[zpool_data["name"]]["name"]

    return ret