{"record":{"id":"909d8e324a7fd3aa","repo":"langchain-ai/langchain","slug":"install-grandalf-to-draw-graphs-pip-install-gran","errorCode":null,"errorMessage":"Install grandalf to draw graphs: `pip install grandalf`.","messagePattern":"Install grandalf to draw graphs: `pip install grandalf`\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/graph_ascii.py","lineNumber":206,"sourceCode":"        self.point(x0 + width, y0, \"+\")\n        self.point(x0, y0 + height, \"+\")\n        self.point(x0 + width, y0 + height, \"+\")\n\n\nclass _EdgeViewer:\n    def __init__(self) -> None:\n        self.pts: list[tuple[float]] = []\n\n    def setpath(self, pts: list[tuple[float]]) -> None:\n        self.pts = pts\n\n\ndef _build_sugiyama_layout(\n    vertices: Mapping[str, str], edges: Sequence[LangEdge]\n) -> Any:\n    if not _HAS_GRANDALF:\n        msg = \"Install grandalf to draw graphs: `pip install grandalf`.\"\n        raise ImportError(msg)\n\n    #\n    # Just a reminder about naming conventions:\n    # +------------X\n    # |\n    # |\n    # |\n    # |\n    # Y\n    #\n\n    vertices_ = {id_: Vertex(f\" {data} \") for id_, data in vertices.items()}\n    edges_ = [Edge(vertices_[s], vertices_[e], data=cond) for s, e, _, cond in edges]\n    vertices_list = vertices_.values()\n    graph = Graph(vertices_list, edges_)\n\n    for vertex in vertices_list:\n        vertex.view = VertexViewer(vertex.data)","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/graph_ascii.py#L188-L224","documentation":"draw_ascii() builds a sugiyama layout using the optional grandalf package. If the import of grandalf failed at module load time (_HAS_GRANDALF is False), _build_sugiyama_layout raises this ImportError instead of an opaque NameError. It tells you exactly which extra to install.","triggerScenarios":"Calling graph.draw_ascii() (or graph_ascii.draw_ascii) in an environment where grandalf is not installed or failed to import.","commonSituations":"Fresh venv/container with only langchain-core installed; grandalf is an optional dependency and is not pulled in by default; CI environments that strip extras.","solutions":["Install grandalf: pip install grandalf (or uv add grandalf / uv sync --group dev if working in the monorepo)","Verify with python -c \"import grandalf\"","Alternatively use graph.draw_mermaid() which needs no extra dependency"],"exampleFix":"# before\ngraph.draw_ascii() # ImportError\n# after\npip install grandalf\ngraph.draw_ascii()","handlingStrategy":"validation","validationCode":"try:\n    import grandalf  # noqa: F401\n    HAS_GRANDALF = True\nexcept ImportError:\n    HAS_GRANDALF = False\n\nif not HAS_GRANDALF:\n    raise RuntimeError(\"grandalf required for draw_ascii(); pip install grandalf\")","typeGuard":null,"tryCatchPattern":"try:\n    art = graph.draw_ascii()\nexcept ImportError as e:\n    if \"grandalf\" in str(e):\n        art = graph.draw_mermaid()","preventionTips":["Add grandalf to your project dependencies if you render ASCII graphs","Check optional imports at app startup instead of failing mid-request"],"tags":["graph","ascii-rendering","missing-dependency","importerror","grandalf"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}