deepset-ai/haystack · error · PipelineDrawingError
The Mermaid server returned an empty response; no image will
Error message
The Mermaid server returned an empty response; no image will be saved.
What it means
Before saving a pipeline diagram, Haystack validates the HTTP response from the Mermaid rendering server. If the response body is empty, no image exists to save, so a PipelineDrawingError is raised to avoid writing an empty/corrupt file to disk.
Source
Thrown at haystack/core/pipeline/draw.py:200
"""
Validate that the Mermaid server response actually contains the expected image/SVG/PDF data.
`Pipeline.draw()` writes the raw response body to disk, so a misconfigured or malicious
`server_url` could otherwise cause arbitrary content (e.g. an HTML error page or a crafted
payload) to be written verbatim to the output path. As defense-in-depth we check both the
`Content-Type` header (which the server controls and could spoof) and the response body's
magic-byte signature (which is harder to forge while still producing a usable payload).
:param resp:
The HTTP response returned by the Mermaid server.
:param params:
Validated Mermaid parameters; used to determine the expected output format.
:raises PipelineDrawingError:
If the response is empty or does not match the expected format.
"""
content = resp.content
if not content:
raise PipelineDrawingError("The Mermaid server returned an empty response; no image will be saved.")
output_format = params.get("format", "img")
img_type = params.get("type", "png")
# (human-readable label, expected Content-Type prefix, body signature check)
content_type_prefixes: tuple[str, ...]
if output_format == "svg":
expected_label = "SVG"
content_type_prefixes = ("image/svg+xml", "text/xml", "application/xml")
stripped = content.lstrip()[:512].lower()
body_ok = stripped.startswith(_SVG_PREFIXES) or _SVG_PREFIXES[1] in stripped
elif output_format == "pdf":
expected_label = "PDF"
content_type_prefixes = ("application/pdf",)
body_ok = content.startswith(_PDF_SIGNATURE)
elif img_type == "jpeg":
expected_label = "JPEG image"
content_type_prefixes = ("image/jpeg",)View on GitHub (pinned to e318778c9b)
Solutions
- Check server_url is a working Mermaid renderer (e.g., https://mermaid.ink) and reachable with curl
- Inspect the logged warning/stacktrace from the underlying request for the actual failure
- If self-hosting, check the renderer's logs and scale/restart it
- Retry after transient network issues
Example fix
// before pipeline.draw(path="graph.png", server_url="http://internal-proxy") // after pipeline.draw(path="graph.png", server_url="https://mermaid.ink")
Defensive patterns
Strategy: try-catch
Validate before calling
import requests
r = requests.head(server_url, timeout=10)
if r.status_code >= 400:
raise RuntimeError(f"Mermaid server {server_url} unreachable") Type guard
def server_reachable(url: str) -> bool:
try:
return requests.get(url, timeout=5).status_code < 400
except requests.RequestException:
return False Try / catch
from haystack.core.errors import PipelineDrawingError
try:
pipeline.draw(path="graph.png")
except PipelineDrawingError as e:
logger.error("Mermaid render failed: %s", e) # fall back / skip diagram Prevention
- Verify server_url with curl before automated runs
- Handle rate limits and outages with retries
- Prefer self-hosted renderer in CI where internet is restricted
When it happens
Trigger: Calling Pipeline.draw() against a Mermaid server (mermaid.ink or self-hosted, via server_url) that returns an HTTP 200 (or any non-exception) response with an empty body.
Common situations: A misconfigured server_url pointing to a proxy or load balancer that answers with empty bodies, a rate-limited server returning empty responses, a self-hosted mermaid renderer that failed internally, or a captive-portal/HTML gateway swallowing the request.
Related errors
- There was an issue with {server_url}, see the stacktrace for
- Paper size must be a string (e.g., 'a4', 'a3').
- Landscape must be a boolean.
- The Mermaid server response does not look like a valid {expe
- Invalid format: {endpoint_format}. Valid options are 'img',
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/122efd1a105635e7.
Report an issue: GitHub.