# Buggy code
def _call_parallel_target(self, name, cdata, low):
    """
    The target function to call that will create the parallel thread/process
    """
    # we need to re-record start/end duration here because it is impossible to
    # correctly calculate further down the chain
    utc_start_time = datetime.datetime.utcnow()

    tag = _gen_tag(low)
    try:
        ret = self.states[cdata["full"]](*cdata["args"], **cdata["kwargs"])
    except Exception:
        trb = traceback.format_exc()
        ret = {
            "result": False,
            "name": name,
            "changes": {},
            "comment": "An exception occurred in this state: {0}".format(trb),
        }

    utc_finish_time = datetime.datetime.utcnow()
    delta = utc_finish_time - utc_start_time
    # duration in milliseconds.microseconds
    duration = (delta.seconds * 1000000 + delta.microseconds) / 1000.0
    ret["duration"] = duration

    troot = os.path.join(self.opts["cachedir"], self.jid)
    tfile = os.path.join(troot, _clean_tag(tag))
    if not os.path.isdir(troot):
        try:
            os.makedirs(troot)
        except OSError:
            # Looks like the directory was created between the check
            # and the attempt, we are safe to pass
            pass
    with salt.utils.fopen(tfile, "wb+") as fp_:
        fp_.write(msgpack_serialize(ret))


# Traceback (IOError)
[testuser@testvm ~]$ salt-call -l debug state.apply dummy
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Using cached minion ID from /etc/salt/minion_id: testvm.office.imp
[DEBUG   ] Configuration file path: /etc/salt/minion
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from /etc/salt/minion
[INFO    ] Although 'virt-what' was found in path, the current user cannot execute it. Grains output might not be accurate.
[DEBUG   ] Determining pillar cache
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded state.apply
[DEBUG   ] LazyLoaded saltutil.is_running
[DEBUG   ] LazyLoaded grains.get
[DEBUG   ] LazyLoaded config.get
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[DEBUG   ] Determining pillar cache
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[INFO    ] Loading fresh modules for state activity
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] In saltenv 'base', looking at rel_path 'dummy.sls' to resolve 'salt://dummy.sls'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/minion/files/base/dummy.sls' to resolve 'salt://dummy.sls'
[DEBUG   ] compile template: /var/cache/salt/minion/files/base/dummy.sls
[DEBUG   ] Jinja search path: [u'/var/cache/salt/minion/files/base']
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[PROFILE ] Time (in seconds) to render '/var/cache/salt/minion/files/base/dummy.sls' using 'jinja' renderer: 0.0155320167542
[DEBUG   ] Rendered data from file: /var/cache/salt/minion/files/base/dummy.sls:
test_cmd_too_long:
cmd.run:
- name: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte
- parallel: True

test_cmd_not_found:
cmd.run:
- name: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte
- parallel: True
[DEBUG   ] Results of YAML rendering:
OrderedDict([(u'test_cmd_too_long', OrderedDict([(u'cmd.run', [OrderedDict([(u'name', u'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte')]), OrderedDict([(u'parallel', True)])])])), (u'test_cmd_not_found', OrderedDict([(u'cmd.run', [OrderedDict([(u'name', u'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte')]), OrderedDict([(u'parallel', True)])])]))])
[PROFILE ] Time (in seconds) to render '/var/cache/salt/minion/files/base/dummy.sls' using 'yaml' renderer: 0.00245714187622
[DEBUG   ] LazyLoaded config.option
[DEBUG   ] LazyLoaded cmd.run
[INFO    ] Running state [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte] at time 12:03:10.046946
[INFO    ] Executing state cmd.run for [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte]
[INFO    ] Started in a separate process
[INFO    ] Completed state [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte] at time 12:03:10.051631 (duration_in_ms=4.685)
[INFO    ] Running state [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte] at time 12:03:10.052327
[INFO    ] Executing state cmd.run for [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte]
[INFO    ] Started in a separate process
[INFO    ] Completed state [testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte] at time 12:03:10.055657 (duration_in_ms=3.33)
[DEBUG   ] LazyLoaded cmd.run_all
[INFO    ] Executing command 'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte' in directory '/home/testuser'
[DEBUG   ] LazyLoaded cmd.run_all
[INFO    ] Executing command 'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte' in directory '/home/testuser'
[ERROR   ] Command 'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte' failed with return code: 127
[ERROR   ] stderr: /bin/bash: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte: command not found
[ERROR   ] retcode: 127
[ERROR   ] An un-handled exception from the multiprocessing process 'MultiprocessingProcess-1' was caught:
Traceback (most recent call last):
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/utils/process.py", line 747, in _run
return self._original_run()
File "/opt/anaconda2/envs/cronos/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/state.py", line 1751, in _call_parallel_target
with salt.utils.files.fopen(tfile, 'wb+') as fp_:
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/utils/files.py", line 386, in fopen
f_handle = open(*args, **kwargs)  # pylint: disable=resource-leakage
IOError: [Errno 36] File name too long: u'/var/cache/salt/minion/20180921120309891759/cmd_%7C-test_cmd_too_long_%7C-testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte_%7C-run'
Process MultiprocessingProcess-1:
Traceback (most recent call last):
File "/opt/anaconda2/envs/cronos/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/utils/process.py", line 747, in _run
return self._original_run()
File "/opt/anaconda2/envs/cronos/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/state.py", line 1751, in _call_parallel_target
with salt.utils.files.fopen(tfile, 'wb+') as fp_:
File "/opt/anaconda2/envs/cronos/lib/python2.7/site-packages/salt/utils/files.py", line 386, in fopen
f_handle = open(*args, **kwargs)  # pylint: disable=resource-leakage
IOError: [Errno 36] File name too long: u'/var/cache/salt/minion/20180921120309891759/cmd_%7C-test_cmd_too_long_%7C-testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte_%7C-run'
[ERROR   ] Command 'testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte' failed with return code: 127
[ERROR   ] stderr: /bin/bash: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte: command not found
[ERROR   ] retcode: 127
[DEBUG   ] File /var/cache/salt/minion/accumulator/140192523746128 does not exist, no need to cleanup
[DEBUG   ] LazyLoaded state.check_result
[DEBUG   ] LazyLoaded highstate.output
[DEBUG   ] LazyLoaded nested.output
local:
----------
ID: test_cmd_too_long
Function: cmd.run
Name: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte
Result: False
Comment: Parallel cache failure
Started: 12:03:10.046946
Duration: 4.685 ms
Changes:
----------
ID: test_cmd_not_found
Function: cmd.run
Name: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte
Result: False
Comment: Command "testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte" run
Started: 12:03:10.052327
Duration: 11.945 ms
Changes:
----------
pid:
22722
retcode:
127
stderr:
/bin/bash: testcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandtestcommandte: command not found
stdout:

Summary for local
------------
Succeeded: 0 (changed=1)
Failed:    2
------------
Total states run:     2
Total run time:  16.630 ms

# Fixed code
def _call_parallel_target(self, name, cdata, low):
    """
    The target function to call that will create the parallel thread/process
    """
    # we need to re-record start/end duration here because it is impossible to
    # correctly calculate further down the chain
    utc_start_time = datetime.datetime.utcnow()

    tag = _gen_tag(low)
    try:
        ret = self.states[cdata["full"]](*cdata["args"], **cdata["kwargs"])
    except Exception:
        trb = traceback.format_exc()
        ret = {
            "result": False,
            "name": name,
            "changes": {},
            "comment": "An exception occurred in this state: {0}".format(trb),
        }

    utc_finish_time = datetime.datetime.utcnow()
    delta = utc_finish_time - utc_start_time
    # duration in milliseconds.microseconds
    duration = (delta.seconds * 1000000 + delta.microseconds) / 1000.0
    ret["duration"] = duration

    troot = os.path.join(self.opts["cachedir"], self.jid)
    tfile = os.path.join(troot, salt.utils.hashutils.sha1_digest(tag))
    if not os.path.isdir(troot):
        try:
            os.makedirs(troot)
        except OSError:
            # Looks like the directory was created between the check
            # and the attempt, we are safe to pass
            pass
    with salt.utils.fopen(tfile, "wb+") as fp_:
        fp_.write(msgpack_serialize(ret))