# Buggy code
def render(self, validation_results: ExpectationSuiteValidationResult):
    run_id = validation_results.meta["run_id"]
    if isinstance(run_id, str):
        try:
            run_time = parse(run_id).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
        except (ValueError, TypeError):
            run_time = "__none__"
        run_name = run_id
    elif isinstance(run_id, dict):
        run_name = run_id.get("run_name") or "__none__"
        run_time = run_id.get("run_time") or "__none__"
    elif isinstance(run_id, RunIdentifier):
        run_name = run_id.run_name or "__none__"
        run_time = run_id.run_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

    expectation_suite_name = validation_results.meta["expectation_suite_name"]
    batch_kwargs = validation_results.meta.get("batch_kwargs")

    # add datasource key to batch_kwargs if missing
    if "datasource" not in validation_results.meta.get("batch_kwargs", {}):
        # check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern
        if len(expectation_suite_name.split(".")) == 4:
            batch_kwargs["datasource"] = expectation_suite_name.split(".")[0]

    # Group EVRs by column
    columns = {}
    for evr in validation_results.results:
        if "column" in evr.expectation_config.kwargs:
            column = evr.expectation_config.kwargs["column"]
        else:
            column = "Table-Level Expectations"

        if column not in columns:
            columns[column] = []
        columns[column].append(evr)

    ordered_columns = Renderer._get_column_list_from_evrs(validation_results)

    overview_content_blocks = [
        self._render_validation_header(validation_results),
        self._render_validation_statistics(validation_results=validation_results),
    ]

    collapse_content_blocks = [
        self._render_validation_info(validation_results=validation_results)
    ]

    if validation_results["meta"].get("batch_markers"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_markers"),
                header="Batch Markers",
            )
        )

    if validation_results["meta"].get("batch_kwargs"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_kwargs"),
                header="Batch Kwargs",
            )
        )

    if validation_results["meta"].get("batch_parameters"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_parameters"),
                header="Batch Parameters",
            )
        )

    collapse_content_block = CollapseContent(
        **{
            "collapse_toggle_link": "Show more info...",
            "collapse": collapse_content_blocks,
            "styling": {
                "body": {"classes": ["card", "card-body"]},
                "classes": ["col-12", "p-1"],
            },
        }
    )

    if not self.run_info_at_end:
        overview_content_blocks.append(collapse_content_block)

    sections = [
        RenderedSectionContent(
            **{
                "section_name": "Overview",
                "content_blocks": overview_content_blocks,
            }
        )
    ]

    if "Table-Level Expectations" in columns:
        sections += [
            self._column_section_renderer.render(
                validation_results=columns["Table-Level Expectations"]
            )
        ]

    sections += [
        self._column_section_renderer.render(
            validation_results=columns[column],
        )
        for column in ordered_columns
    ]

    if self.run_info_at_end:
        sections += [
            RenderedSectionContent(
                **{
                    "section_name": "Run Info",
                    "content_blocks": collapse_content_blocks,
                }
            )
        ]

    data_asset_name = batch_kwargs.get("data_asset_name")
    # Determine whether we have a custom run_name
    try:
        run_name_as_time = parse(run_name)
    except ValueError:
        run_name_as_time = None
    try:
        run_time_datetime = parse(run_time)
    except ValueError:
        run_time_datetime = None

    include_run_name: bool = False
    if run_name_as_time != run_time_datetime and run_name_as_time != "__none__":
        include_run_name = True

    page_title = "Validations / " + expectation_suite_name
    if data_asset_name:
        page_title += " / " + data_asset_name
    if include_run_name:
        page_title += " / " + run_name
    page_title += " / " + run_time

    return RenderedDocumentContent(
        **{
            "renderer_type": "ValidationResultsPageRenderer",
            "page_title": page_title,
            "batch_kwargs": batch_kwargs,
            "expectation_suite_name": expectation_suite_name,
            "sections": sections,
            "utm_medium": "validation-results-page",
        }
    )


# Traceback (TypeError)
❯ great_expectations docs build

The following Data Docs sites will be built:

- local_site: file:///Users/taylor/repos/sdap/ge/great_expectations/uncommitted/data_docs/local_site/index.html

Would you like to proceed? [Y/n]:

Building Data Docs...

--- Logging error ---
Traceback (most recent call last):
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 443, in build
rendered_content = self.renderer_class.render(resource)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/page_renderer.py", line 210, in render
page_title += " / " + data_asset_name
TypeError: can only concatenate str (not "int") to str

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/__init__.py", line 1081, in emit
msg = self.format(record)
File "/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/__init__.py", line 925, in format
return fmt.format(record)
File "/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/__init__.py", line 664, in format
record.message = record.getMessage()
File "/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/logging/__init__.py", line 369, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "/Users/taylor/repos/sdap/.venv/bin/great_expectations", line 8, in <module>
sys.exit(main())
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/cli.py", line 73, in main
cli()
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/docs.py", line 45, in docs_build
build_docs(context, site_name=site_name, view=view, assume_yes=assume_yes)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/docs.py", line 146, in build_docs
index_page_locator_infos = context.build_data_docs(site_names=site_names)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/core/usage_statistics/usage_statistics.py", line 257, in usage_statistics_wrapped_method
result = func(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/data_context/data_context.py", line 1572, in build_data_docs
index_page_resource_identifier_tuple = site_builder.build(
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 290, in build
site_section_builder.build(resource_identifiers=resource_identifiers)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 460, in build
logger.error(exception_message, e, exc_info=True)
Message: 'An unexpected Exception occurred during data docs rendering.  Because of this error, certain parts of data docs will not be rendered properly and/or may not appear altogether.  Please use the trace, included in this message, to diagnose and repair the underlying issue.  Detailed information follows:\n                TypeError: "can only concatenate str (not "int") to str".  Traceback: "Traceback (most recent call last):\n  File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 443, in build\n    rendered_content = self.renderer_class.render(resource)\n  File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/page_renderer.py", line 210, in render\n    page_title += " / " + data_asset_name\nTypeError: can only concatenate str (not "int") to str\n".'
Arguments: (TypeError('can only concatenate str (not "int") to str'),)
Traceback (most recent call last):
File "/Users/taylor/repos/sdap/.venv/bin/great_expectations", line 8, in <module>
sys.exit(main())
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/cli.py", line 73, in main
cli()
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/docs.py", line 45, in docs_build
build_docs(context, site_name=site_name, view=view, assume_yes=assume_yes)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/cli/docs.py", line 146, in build_docs
index_page_locator_infos = context.build_data_docs(site_names=site_names)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/core/usage_statistics/usage_statistics.py", line 257, in usage_statistics_wrapped_method
result = func(*args, **kwargs)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/data_context/data_context.py", line 1572, in build_data_docs
index_page_resource_identifier_tuple = site_builder.build(
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 290, in build
site_section_builder.build(resource_identifiers=resource_identifiers)
File "/Users/taylor/repos/sdap/.venv/lib/python3.8/site-packages/great_expectations/render/renderer/site_builder.py", line 466, in build
viewable_content,
UnboundLocalError: local variable 'viewable_content' referenced before assignment

# Fixed code
def render(self, validation_results: ExpectationSuiteValidationResult):
    run_id = validation_results.meta["run_id"]
    if isinstance(run_id, str):
        try:
            run_time = parse(run_id).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
        except (ValueError, TypeError):
            run_time = "__none__"
        run_name = run_id
    elif isinstance(run_id, dict):
        run_name = run_id.get("run_name") or "__none__"
        run_time = run_id.get("run_time") or "__none__"
    elif isinstance(run_id, RunIdentifier):
        run_name = run_id.run_name or "__none__"
        run_time = run_id.run_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

    expectation_suite_name = validation_results.meta["expectation_suite_name"]
    batch_kwargs = validation_results.meta.get("batch_kwargs")

    # add datasource key to batch_kwargs if missing
    if "datasource" not in validation_results.meta.get("batch_kwargs", {}):
        # check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern
        if len(expectation_suite_name.split(".")) == 4:
            batch_kwargs["datasource"] = expectation_suite_name.split(".")[0]

    # Group EVRs by column
    columns = {}
    for evr in validation_results.results:
        if "column" in evr.expectation_config.kwargs:
            column = evr.expectation_config.kwargs["column"]
        else:
            column = "Table-Level Expectations"

        if column not in columns:
            columns[column] = []
        columns[column].append(evr)

    ordered_columns = Renderer._get_column_list_from_evrs(validation_results)

    overview_content_blocks = [
        self._render_validation_header(validation_results),
        self._render_validation_statistics(validation_results=validation_results),
    ]

    collapse_content_blocks = [
        self._render_validation_info(validation_results=validation_results)
    ]

    if validation_results["meta"].get("batch_markers"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_markers"),
                header="Batch Markers",
            )
        )

    if validation_results["meta"].get("batch_kwargs"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_kwargs"),
                header="Batch Kwargs",
            )
        )

    if validation_results["meta"].get("batch_parameters"):
        collapse_content_blocks.append(
            self._render_nested_table_from_dict(
                input_dict=validation_results["meta"].get("batch_parameters"),
                header="Batch Parameters",
            )
        )

    collapse_content_block = CollapseContent(
        **{
            "collapse_toggle_link": "Show more info...",
            "collapse": collapse_content_blocks,
            "styling": {
                "body": {"classes": ["card", "card-body"]},
                "classes": ["col-12", "p-1"],
            },
        }
    )

    if not self.run_info_at_end:
        overview_content_blocks.append(collapse_content_block)

    sections = [
        RenderedSectionContent(
            **{
                "section_name": "Overview",
                "content_blocks": overview_content_blocks,
            }
        )
    ]

    if "Table-Level Expectations" in columns:
        sections += [
            self._column_section_renderer.render(
                validation_results=columns["Table-Level Expectations"]
            )
        ]

    sections += [
        self._column_section_renderer.render(
            validation_results=columns[column],
        )
        for column in ordered_columns
    ]

    if self.run_info_at_end:
        sections += [
            RenderedSectionContent(
                **{
                    "section_name": "Run Info",
                    "content_blocks": collapse_content_blocks,
                }
            )
        ]

    data_asset_name = batch_kwargs.get("data_asset_name")
    # Determine whether we have a custom run_name
    try:
        run_name_as_time = parse(run_name)
    except ValueError:
        run_name_as_time = None
    try:
        run_time_datetime = parse(run_time)
    except ValueError:
        run_time_datetime = None

    include_run_name: bool = False
    if run_name_as_time != run_time_datetime and run_name_as_time != "__none__":
        include_run_name = True

    page_title = "Validations / " + str(expectation_suite_name)
    if data_asset_name:
        page_title += " / " + str(data_asset_name)
    if include_run_name:
        page_title += " / " + str(run_name)
    page_title += " / " + str(run_time)

    return RenderedDocumentContent(
        **{
            "renderer_type": "ValidationResultsPageRenderer",
            "page_title": page_title,
            "batch_kwargs": batch_kwargs,
            "expectation_suite_name": expectation_suite_name,
            "sections": sections,
            "utm_medium": "validation-results-page",
        }
    )