HKUDS/DeepTutor · error · GenerationFailure
concept_graph payload missing from BlockContext.extra
Error message
concept_graph payload missing from BlockContext.extra
What it means
The concept_graph block needs a ConceptGraph payload and looks it up in `ctx.extra['concept_graph']` then `ctx.block.params['concept_graph']`; when neither is present it fails generation with this message.
Source
Thrown at deeptutor/book/blocks/concept_graph.py:91
arrow_for = {"depends_on": "-->", "extends": "==>", "related": "-.->"}
for edge in graph.edges:
if edge.src not in id_map or edge.dst not in id_map:
continue
arrow = arrow_for.get(edge.relation, "-->")
lines.append(f" {id_map[edge.src]} {arrow} {id_map[edge.dst]}")
return "\n".join(lines)
class ConceptGraphGenerator(BlockGenerator):
block_type = BlockType.CONCEPT_GRAPH
async def _generate(
self, ctx: BlockContext
) -> tuple[dict[str, Any], list[SourceAnchor], dict[str, Any]]:
raw = ctx.extra.get("concept_graph") or ctx.block.params.get("concept_graph")
if raw is None:
raise GenerationFailure("concept_graph payload missing from BlockContext.extra")
if isinstance(raw, ConceptGraph):
graph = raw
elif isinstance(raw, dict):
try:
graph = ConceptGraph.model_validate(raw)
except Exception as exc:
raise GenerationFailure(f"invalid concept_graph payload: {exc}") from exc
else:
raise GenerationFailure(f"unexpected concept_graph payload type: {type(raw).__name__}")
chapters_index = ctx.extra.get("chapter_index") or []
if not isinstance(chapters_index, list):
chapters_index = []
mermaid_src = render_mermaid(graph)
# Build a node→chapter lookup for the interactive sidebar.
node_to_chapter: dict[str, str] = {}View on GitHub (pinned to 3e82f13042)
Solutions
- Pass the ConceptGraph when building the context: put it in extra under 'concept_graph' or into block params
- If driving the standard compiler, ensure the concept-graph extraction stage runs before block generation
- If a one-off render, construct `ConceptGraph(...)` and inject it explicitly
Example fix
# before
ctx = BlockContext(block=block, language="en", extra={})
# after
ctx = BlockContext(
block=block,
language="en",
extra={"concept_graph": my_concept_graph},
) Defensive patterns
Strategy: validation
Validate before calling
if "concept_graph" not in ctx.extra and "concept_graph" not in (ctx.block.params or {}):
raise ValueError("inject concept_graph before generating concept_graph blocks") Type guard
def has_graph_payload(ctx) -> bool:
return ctx.extra.get("concept_graph") is not None or \
ctx.block.params.get("concept_graph") is not None Try / catch
from deeptutor.book.compiler import GenerationFailure
try:
await cg_gen._generate(ctx)
except GenerationFailure as e:
if "payload missing" in str(e):
ctx.extra["concept_graph"] = build_graph(chapters)
return await cg_gen._generate(ctx)
raise Prevention
- Run graph extraction before block generation in custom pipelines
- Always populate BlockContext.extra when constructing contexts by hand
When it happens
Trigger: Compiling a book whose outline contains a `concept_graph` block while the caller (pipeline/compiler) forgot to inject the graph into BlockContext.extra, and the block params don't carry it either — e.g. custom pipelines constructing BlockContext by hand.
Common situations: Building your own generation pipeline and passing a bare BlockContext; reordering compiler stages so graph extraction runs after block generation; serializing/deserializing contexts and dropping `extra`.
Related errors
- Model not configured for agent {self.agent_name}. Please act
- Render failed because local LaTeX is missing. Please avoid T
- Document not found
- Unsupported import source: {value!r}
- Invalid folder path
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/192d7777279e0229.
Report an issue: GitHub.