# Buggy code
def unhold(name=None, pkgs=None, sources=None, **kwargs):  # pylint: disable=W0613
    """
    .. versionadded:: 2014.7.0

    Set package current in 'hold' state to install state,
    meaning it will be upgraded.

    name
        The name of the package, e.g., 'tmux'

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.unhold <package name>

    pkgs
        A list of packages to hold. Must be passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.unhold pkgs='["foo", "bar"]'
    """
    if not name and not pkgs and not sources:
        raise SaltInvocationError("One of name, pkgs, or sources must be specified.")
    if pkgs and sources:
        raise SaltInvocationError("Only one of pkgs or sources can be specified.")

    targets = []
    if pkgs:
        targets.extend(pkgs)
    elif sources:
        for source in sources:
            targets.append(next(iter(source)))
    else:
        targets.append(name)

    ret = {}
    for target in targets:
        if isinstance(target, dict):
            target = next(iter(target))

        ret[target] = {"name": target, "changes": {}, "result": False, "comment": ""}

        state = get_selections(pattern=target)
        if not state:
            ret[target]["comment"] = "Package {0} does not have a state.".format(target)
        elif salt.utils.is_true(state.get("hold", False)):
            if "test" in __opts__ and __opts__["test"]:
                ret[target].update(result=None)
                ret["comment"] = "Package {0} is set not to be held.".format(target)
            else:
                result = set_selections(selection={"install": [target]})
                ret[target].update(changes=result[target], result=True)
                ret[target]["comment"] = "Package {0} is no longer being held.".format(
                    target
                )
        else:
            ret[target].update(result=True)
            ret[target]["comment"] = (
                "Package {0} is already set not to be held.".format(target)
            )
    return ret


# Traceback (TypeError)
ID: logstash-unhold
Function: pkg.installed
Name: logstash
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1746, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 1704, in wrapper
return f(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/salt/states/pkg.py", line 1326, in installed
if hold_ret[x]['changes']]
TypeError: string indices must be integers, not str
Started: 16:39:23.464969
Duration: 27.297 ms
Changes:

# Fixed code
def unhold(name=None, pkgs=None, sources=None, **kwargs):  # pylint: disable=W0613
    """
    .. versionadded:: 2014.7.0

    Set package current in 'hold' state to install state,
    meaning it will be upgraded.

    name
        The name of the package, e.g., 'tmux'

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.unhold <package name>

    pkgs
        A list of packages to hold. Must be passed as a python list.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.unhold pkgs='["foo", "bar"]'
    """
    if not name and not pkgs and not sources:
        raise SaltInvocationError("One of name, pkgs, or sources must be specified.")
    if pkgs and sources:
        raise SaltInvocationError("Only one of pkgs or sources can be specified.")

    targets = []
    if pkgs:
        targets.extend(pkgs)
    elif sources:
        for source in sources:
            targets.append(next(iter(source)))
    else:
        targets.append(name)

    ret = {}
    for target in targets:
        if isinstance(target, dict):
            target = next(iter(target))

        ret[target] = {"name": target, "changes": {}, "result": False, "comment": ""}

        state = get_selections(pattern=target)
        if not state:
            ret[target]["comment"] = "Package {0} does not have a state.".format(target)
        elif salt.utils.is_true(state.get("hold", False)):
            if "test" in __opts__ and __opts__["test"]:
                ret[target].update(result=None)
                ret[target]["comment"] = "Package {0} is set not to be held.".format(
                    target
                )
            else:
                result = set_selections(selection={"install": [target]})
                ret[target].update(changes=result[target], result=True)
                ret[target]["comment"] = "Package {0} is no longer being held.".format(
                    target
                )
        else:
            ret[target].update(result=True)
            ret[target]["comment"] = (
                "Package {0} is already set not to be held.".format(target)
            )
    return ret