Skip to content

MarkdownString tables aren't rendered #808

@strickvl

Description

@strickvl

Reported in Slack originally. Here's code to reproduce the behaviour:

from zenml import pipeline, step
from zenml.types import MarkdownString


@step(enable_artifact_visualization=True)
def emit_markdown_table() -> MarkdownString:
    """Produce multiple table formats as a single MarkdownString.

    Includes several variants to test renderer behavior:
    - Variant 1: GFM alignment markers
    - Variant 2: Standard Markdown separators (---)
    - Variant 3: Table preceded by a horizontal rule (---)
    - Variant 4: Minimalist syntax (no alignment markers, compact spacing)
    """
    md = (
        "### Variant 1 – GFM alignment markers\n"
        "\n"
        "| Metric    |   Value | Status |\n"
        "|:----------|--------:|:------:|\n"
        "| Accuracy  |   0.912 |  pass  |\n"
        "| Precision |   0.877 |  pass  |\n"
        "| Recall    |   0.832 |  warn  |\n"
        "| F1-Score  |   0.872 |  pass  |\n"
        "\n"
        "### Variant 2 – Standard Markdown separators (no alignment)\n"
        "\n"
        "| Metric    | Value | Status |\n"
        "| ---       | ---   | ---    |\n"
        "| Accuracy  | 0.912 | pass   |\n"
        "| Precision | 0.877 | pass   |\n"
        "| Recall    | 0.832 | warn   |\n"
        "| F1-Score  | 0.872 | pass   |\n"
        "\n"
        "### Variant 3 – Horizontal rule before the table\n"
        "\n"
        "---\n"
        "\n"
        "| Metric | Value | Status |\n"
        "| ---    | ---   | ---    |\n"
        "| A      | 1     | ok     |\n"
        "| B      | 2     | ok     |\n"
        "| C      | 3     | warn   |\n"
        "\n"
        "### Variant 4 – Minimalist table syntax (no leading/trailing pipes, compact spacing)\n"
        "\n"
        "Name|Score|Note\n"
        "---|---|---\n"
        "Alpha|10|ok\n"
        "Beta|5|meh\n"
        "Gamma|7|ok\n"
    )
    return MarkdownString(md)


@pipeline
def markdown_viz_pipeline():
    """Single-step pipeline that emits a Markdown table."""
    emit_markdown_table()


if __name__ == "__main__":
    markdown_viz_pipeline()

...which you can see rendered in the dashboard here: https://cloud.zenml.io/workspaces/internal/projects/default/artifact-versions/7df72d21-37c2-46d3-9abd-547d72f4eacd?tab=visualization#output.md.

Image

Root Cause

  • zenml-dashboard/src/components/artifacts/MarkdownVisualization.tsx:5 renders artifact Markdown with react-markdown alone, so only CommonMark syntax is parsed; GitHub-style tables are treated as plain text.
  • The pipeline summary view repeats the same pattern in zenml-dashboard/src/app/overview/pipelines-grid/pipeline-sheet.tsx:167, meaning end users see raw pipe/table syntax there as well.
  • zenml-dashboard/package.json lists react-markdown@^9.0.3 but no remark-gfm, confirming the bundle never enables GitHub-Flavored Markdown.

Recommended Fix

  • Add remark-gfm (v4.x matches the current unified stack) to zenml-dashboard/package.json.
  • Import it and pass remarkPlugins={[remarkGfm]} wherever Markdown is rendered—at minimum in src/components/artifacts/MarkdownVisualization.tsx and src/app/overview/pipelines-grid/pipeline- sheet.tsx—so tables, task lists, and autolinks parse correctly while leaving raw HTML disabled.
    • Optionally wrap this in a shared Markdown component to keep future settings consistent and ensure anchors get target="_blank"/rel="noopener noreferrer".

A suggested fix for zenml-dashboard is implemented in PR #807. From what I understand, a similar fix might need to be applied to zenml-cloud-ui as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions