# Buggy code
def transform_parameter(self):
    # Depreciated placeholders:
    # - $[taskcat_gets3contents]
    # - $[taskcat_geturl]
    for param_name, param_value in self._param_dict.items():
        # Setting the instance variables to reflect key/value pair we're working on.
        self.param_name = param_name
        self.param_value = param_value

        # Convert from bytes to string.
        self.convert_to_str()

        # $[taskcat_random-numbers]
        self._regex_replace_param_value(self.RE_GENNUMB, self._gen_rand_num(20))

        # $[taskcat_random-string]
        self._regex_replace_param_value(self.RE_GENRANDSTR, self._gen_rand_str(20))

        # $[taskcat_autobucket]
        self._regex_replace_param_value(self.RE_GENAUTOBUCKET, self._gen_autobucket())

        # $[taskcat_genpass_X]
        self._gen_password_wrapper(self.RE_GENPW, self.RE_PWTYPE, self.RE_COUNT)

        # $[taskcat_ge[nt]az_#]
        self._gen_az_wrapper(self.RE_GENAZ, self.RE_COUNT)

        # $[taskcat_ge[nt]singleaz_#]
        self._gen_single_az_wrapper(self.RE_GENAZ_SINGLE)

        # $[taskcat_getkeypair]
        self._regex_replace_param_value(self.RE_QSKEYPAIR, "cikey")

        # $[taskcat_getlicensebucket]
        self._regex_replace_param_value(self.RE_QSLICBUCKET, "override_this")

        # $[taskcat_getmediabucket]
        self._regex_replace_param_value(self.RE_QSMEDIABUCKET, "override_this")

        # $[taskcat_getlicensecontent]
        self._get_license_content_wrapper(self.RE_GETLICCONTENT)

        # $[taskcat_getpresignedurl]
        self._get_license_content_wrapper(self.RE_GETPRESIGNEDURL)

        # $[taskcat_getval_X]
        self._getval_wrapper(self.RE_GETVAL)

        # $[taskcat_genuuid]
        self._regex_replace_param_value(self.RE_GENUUID, self._gen_uuid())
        self.results.update({self.param_name: self.param_value})


# Traceback (TypeError)
taskcat -d test run
_            _             _
| |_ __ _ ___| | _____ __ _| |_
| __/ _` / __| |/ / __/ _` | __|
| || (_| \__ \   < (_| (_| | |_
\__\__,_|___/_|\_\___\__,_|\__|



version 0.9.8
/home/ubuntu/.local/lib/python3.6/site-packages/dataclasses_jsonschema/__init__.py:457: UserWarning: Unable to decode value for 'parameters: str'
warnings.warn(f"Unable to decode value for '{field}: {field_type_name}'")
[INFO   ] : Lint passed for test mytest on template /home/ubuntu/taskcatrun/Create_ALB.template
[S3: -> ] s3://tcat-taskcat-poc-nlsq599i/taskcat-poc/Create_ALB.template
[ERROR  ] : TypeError expected string or bytes-like object
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_cli.py", line 70, in main
cli.run()
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_cli_core.py", line 228, in run
return getattr(command(), subcommand)(**args)
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_cli_modules/test.py", line 75, in run
parameters = config.get_rendered_parameters(buckets, regions, templates)
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_config.py", line 295, in get_rendered_parameters
region_params, s3bucket.name, region.name, region.client
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_template_params.py", line 61, in __init__
self.transform_parameter()
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_template_params.py", line 76, in transform_parameter
self._regex_replace_param_value(self.RE_GENNUMB, self._gen_rand_num(20))
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_template_params.py", line 348, in _regex_replace_param_value
if self.regxfind(regex_pattern, self.param_value):
File "/home/ubuntu/.local/lib/python3.6/site-packages/taskcat/_common_utils.py", line 75, in regxfind
security_group = re_object.search(data_line)
TypeError: expected string or bytes-like object
ubuntu@ubuntu-VirtualBox:~/taskcatrun$

# Fixed code
def transform_parameter(self):
    # Depreciated placeholders:
    # - $[taskcat_gets3contents]
    # - $[taskcat_geturl]
    for param_name, param_value in self._param_dict.items():
        if isinstance(param_value, list):
            _results_list = []
            _nested_param_dict = {}
            for idx, value in enumerate(param_value):
                _nested_param_dict[idx] = value
            nested_pg = ParamGen(
                _nested_param_dict,
                self.bucket_name,
                self.region,
                self._boto_client,
                self.az_excludes,
            )
            nested_pg.transform_parameter()
            for result_value in nested_pg.results.values():
                _results_list.append(result_value)
            self.param_value = _results_list
            self.results.update({param_name: _results_list})
            continue

        # Setting the instance variables to reflect key/value pair we're working on.
        self.param_name = param_name
        self.param_value = param_value

        # Convert from bytes to string.
        self.convert_to_str()

        # $[taskcat_random-numbers]
        self._regex_replace_param_value(self.RE_GENNUMB, self._gen_rand_num(20))

        # $[taskcat_random-string]
        self._regex_replace_param_value(self.RE_GENRANDSTR, self._gen_rand_str(20))

        # $[taskcat_autobucket]
        self._regex_replace_param_value(self.RE_GENAUTOBUCKET, self._gen_autobucket())

        # $[taskcat_genpass_X]
        self._gen_password_wrapper(self.RE_GENPW, self.RE_PWTYPE, self.RE_COUNT)

        # $[taskcat_ge[nt]az_#]
        self._gen_az_wrapper(self.RE_GENAZ, self.RE_COUNT)

        # $[taskcat_ge[nt]singleaz_#]
        self._gen_single_az_wrapper(self.RE_GENAZ_SINGLE)

        # $[taskcat_getkeypair]
        self._regex_replace_param_value(self.RE_QSKEYPAIR, "cikey")

        # $[taskcat_getlicensebucket]
        self._regex_replace_param_value(self.RE_QSLICBUCKET, "override_this")

        # $[taskcat_getmediabucket]
        self._regex_replace_param_value(self.RE_QSMEDIABUCKET, "override_this")

        # $[taskcat_getlicensecontent]
        self._get_license_content_wrapper(self.RE_GETLICCONTENT)

        # $[taskcat_getpresignedurl]
        self._get_license_content_wrapper(self.RE_GETPRESIGNEDURL)

        # $[taskcat_getval_X]
        self._getval_wrapper(self.RE_GETVAL)

        # $[taskcat_genuuid]
        self._regex_replace_param_value(self.RE_GENUUID, self._gen_uuid())
        self.results.update({self.param_name: self.param_value})