deepset-ai/haystack · error · ValueError

Landscape must be a boolean.

Error message

Landscape must be a boolean.

What it means

When rendering a pipeline diagram as PDF via Mermaid.ink, the optional 'landscape' parameter must be a boolean. _validate_mermaid_params raises this ValueError if a truthy/falsy non-boolean (e.g., the strings "true"/"false", or 1/0) is supplied.

Source

Thrown at haystack/core/pipeline/draw.py:167

    if "height" in params and not isinstance(params["height"], int):
        raise ValueError("Height must be an integer.")

    if "scale" in params and not 1 <= params["scale"] <= 3:
        raise ValueError("Scale must be a number between 1 and 3.")
    if "scale" in params and not ("width" in params or "height" in params):
        raise ValueError("Scale is only allowed when width or height is set.")

    if "bgColor" in params and not isinstance(params["bgColor"], str):
        raise ValueError("Background color must be a string.")

    # PDF specific parameters
    if params["format"] == "pdf":
        if "fit" in params and not isinstance(params["fit"], bool):
            raise ValueError("Fit must be a boolean.")
        if "paper" in params and not isinstance(params["paper"], str):
            raise ValueError("Paper size must be a string (e.g., 'a4', 'a3').")
        if "landscape" in params and not isinstance(params["landscape"], bool):
            raise ValueError("Landscape must be a boolean.")
        if "fit" in params and ("paper" in params or "landscape" in params):
            logger.warning("`fit` overrides `paper` and `landscape` for PDFs. Ignoring `paper` and `landscape`.")


# Magic-byte signatures used to verify a Mermaid server response matches the requested output format.
_PNG_SIGNATURE = b"\x89PNG\r\n\x1a\n"
_JPEG_SIGNATURE = b"\xff\xd8\xff"
_PDF_SIGNATURE = b"%PDF-"
_RIFF_SIGNATURE = b"RIFF"
_WEBP_SIGNATURE = b"WEBP"
_SVG_PREFIXES = (b"<?xml", b"<svg")


def _validate_image_response(resp: httpx.Response, params: dict[str, Any]) -> None:
    """
    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

View on GitHub (pinned to e318778c9b)

Solutions

  1. Set params['landscape'] to the Python boolean True or False
  2. Convert string flags with landscape = raw.lower() == 'true'
  3. Note: 'fit': True overrides paper/landscape anyway; consider using fit instead

Example fix

// before
params = {"format": "pdf", "landscape": "true"}
// after
params = {"format": "pdf", "landscape": True}
Defensive patterns

Strategy: type-guard

Validate before calling

if params.get("format") == "pdf" and "landscape" in params and not isinstance(params["landscape"], bool):
    params["landscape"] = params["landscape"] in (True, "true", 1)

Type guard

def is_bool(v) -> bool:
    return isinstance(v, bool)

Try / catch

try:
    pipeline.draw(path="graph.pdf", params=params)
except ValueError as e:
    logger.error("Invalid Mermaid params: %s", e)

Prevention

When it happens

Trigger: Calling Pipeline.draw() or show() with params like {'format': 'pdf', 'landscape': 'true'} or {'format': 'pdf', 'landscape': 1}.

Common situations: Values loaded from environment variables or CLI args are strings ('true'), JSON configs where landscape is 0/1, or users confusing Python bool semantics with string flags.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/833af930e81585f7. Report an issue: GitHub.