# Buggy code
def accumulated(name, filename, text, **kwargs):
    """
    Prepare accumulator which can be used in template in file.managed state.
    Accumulator dictionary becomes available in template. It can also be used
    in file.blockreplace.

    name
        Accumulator name

    filename
        Filename which would receive this accumulator (see file.managed state
        documentation about ``name``)

    text
        String or list for adding in accumulator

    require_in / watch_in
        One of them required for sure we fill up accumulator before we manage
        the file. Probably the same as filename

    Example:

    Given the following:

    .. code-block:: yaml

        animals_doing_things:
          file.accumulated:
            - filename: /tmp/animal_file.txt
            - text: ' jumps over the lazy dog.'
            - require_in:
              - file: animal_file

        animal_file:
          file.managed:
            - name: /tmp/animal_file.txt
            - source: salt://animal_file.txt
            - template: jinja

    One might write a template for ``animal_file.txt`` like the following:

    .. code-block:: jinja

        The quick brown fox{% for animal in accumulator['animals_doing_things'] %}{{ animal }}{% endfor %}

    Collectively, the above states and template file will produce:

    .. code-block:: text

        The quick brown fox jumps over the lazy dog.

    Multiple accumulators can be "chained" together.

    .. note::
        The 'accumulator' data structure is a Python dictionary.
        Do not expect any loop over the keys in a deterministic order!
    """
    ret = {"name": name, "changes": {}, "result": True, "comment": ""}
    if text is None:
        ret["result"] = False
        ret["comment"] = "No text supplied for accumulator"
        return ret
    require_in = __low__.get("require_in", [])
    watch_in = __low__.get("watch_in", [])
    deps = require_in + watch_in
    if not filter(lambda x: "file" in x, deps):
        ret["result"] = False
        ret["comment"] = "Orphaned accumulator {0} in {1}:{2}".format(
            name, __low__["__sls__"], __low__["__id__"]
        )
        return ret
    if isinstance(text, string_types):
        text = (text,)
    if filename not in _ACCUMULATORS:
        _ACCUMULATORS[filename] = {}
    if filename not in _ACCUMULATORS_DEPS:
        _ACCUMULATORS_DEPS[filename] = {}
    if name not in _ACCUMULATORS_DEPS[filename]:
        _ACCUMULATORS_DEPS[filename][name] = []
    for accumulator in deps:
        _ACCUMULATORS_DEPS[filename][name].extend(accumulator.itervalues())
    if name not in _ACCUMULATORS[filename]:
        _ACCUMULATORS[filename][name] = []
    for chunk in text:
        if chunk not in _ACCUMULATORS[filename][name]:
            _ACCUMULATORS[filename][name].append(chunk)
            ret["comment"] = "Accumulator {0} for file {1} was charged by text".format(
                name, filename
            )
    return ret


# Traceback (TypeError)
2014-11-24 16:03:42,245 [salt.minion      ][WARNING ] TypeError encountered executing state.highstate: expected string or buffer. See debug log for more info.  Possibly a missing arguments issue:  ArgSpec(args=['test', 'queue'], varargs=None, keywords='kwargs', defaults=(None, False))
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/salt/minion.py", line 809, in _thread_return
return_data = func(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/salt/modules/state.py", line 275, in highstate
force=kwargs.get('force', False)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 2546, in call_highstate
return self.state.call_high(high)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1715, in call_high
ret = self.call_chunks(chunks)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1437, in call_chunks
running = self.call_chunk(low, running, chunks)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1562, in call_chunk
status = self.check_requisite(low, running, chunks, True)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1489, in check_requisite
if (fnmatch.fnmatch(chunk['name'], req_val) or
File "/usr/lib/python2.7/fnmatch.py", line 43, in fnmatch
return fnmatchcase(name, pat)
File "/usr/lib/python2.7/fnmatch.py", line 79, in fnmatchcase
return _cache[pat].match(name) is not None
TypeError: expected string or buffer

# Fixed code
def accumulated(name, filename, text, **kwargs):
    """
    Prepare accumulator which can be used in template in file.managed state.
    Accumulator dictionary becomes available in template. It can also be used
    in file.blockreplace.

    name
        Accumulator name

    filename
        Filename which would receive this accumulator (see file.managed state
        documentation about ``name``)

    text
        String or list for adding in accumulator

    require_in / watch_in
        One of them required for sure we fill up accumulator before we manage
        the file. Probably the same as filename

    Example:

    Given the following:

    .. code-block:: yaml

        animals_doing_things:
          file.accumulated:
            - filename: /tmp/animal_file.txt
            - text: ' jumps over the lazy dog.'
            - require_in:
              - file: animal_file

        animal_file:
          file.managed:
            - name: /tmp/animal_file.txt
            - source: salt://animal_file.txt
            - template: jinja

    One might write a template for ``animal_file.txt`` like the following:

    .. code-block:: jinja

        The quick brown fox{% for animal in accumulator['animals_doing_things'] %}{{ animal }}{% endfor %}

    Collectively, the above states and template file will produce:

    .. code-block:: text

        The quick brown fox jumps over the lazy dog.

    Multiple accumulators can be "chained" together.

    .. note::
        The 'accumulator' data structure is a Python dictionary.
        Do not expect any loop over the keys in a deterministic order!
    """
    ret = {"name": name, "changes": {}, "result": True, "comment": ""}
    if not name:
        return _error(ret, "Must provide name to file.accumulated")
    if text is None:
        ret["result"] = False
        ret["comment"] = "No text supplied for accumulator"
        return ret
    require_in = __low__.get("require_in", [])
    watch_in = __low__.get("watch_in", [])
    deps = require_in + watch_in
    if not filter(lambda x: "file" in x, deps):
        ret["result"] = False
        ret["comment"] = "Orphaned accumulator {0} in {1}:{2}".format(
            name, __low__["__sls__"], __low__["__id__"]
        )
        return ret
    if isinstance(text, string_types):
        text = (text,)
    if filename not in _ACCUMULATORS:
        _ACCUMULATORS[filename] = {}
    if filename not in _ACCUMULATORS_DEPS:
        _ACCUMULATORS_DEPS[filename] = {}
    if name not in _ACCUMULATORS_DEPS[filename]:
        _ACCUMULATORS_DEPS[filename][name] = []
    for accumulator in deps:
        _ACCUMULATORS_DEPS[filename][name].extend(accumulator.itervalues())
    if name not in _ACCUMULATORS[filename]:
        _ACCUMULATORS[filename][name] = []
    for chunk in text:
        if chunk not in _ACCUMULATORS[filename][name]:
            _ACCUMULATORS[filename][name].append(chunk)
            ret["comment"] = "Accumulator {0} for file {1} was charged by text".format(
                name, filename
            )
    return ret