microsoft/graphrag · error · KeyError
Missing key in context for template '{template_name}': {e.me
Error message
Missing key in context for template '{template_name}': {e.message} What it means
JinjaTemplateEngine.render raises this KeyError when the template compiles fine but references a variable that is not supplied in the render context. Templates are compiled with StrictUndefined, so any missing key aborts rendering instead of silently rendering an empty string.
Source
Thrown at packages/graphrag-llm/graphrag_llm/templating/jinja_template_engine.py:47
"""
self._templates = {}
self._template_manager = template_manager
def render(self, template_name: str, context: dict[str, Any]) -> str:
"""Render a template with the given context."""
jinja_template = self._templates.get(template_name)
if jinja_template is None:
template_contents = self._template_manager.get(template_name)
if template_contents is None:
msg = f"Template '{template_name}' not found."
raise KeyError(msg)
jinja_template = Template(template_contents, undefined=StrictUndefined)
self._templates[template_name] = jinja_template
try:
return jinja_template.render(**context)
except UndefinedError as e:
msg = f"Missing key in context for template '{template_name}': {e.message}"
raise KeyError(msg) from e
except Exception as e:
msg = f"Error rendering template '{template_name}': {e!s}"
raise RuntimeError(msg) from e
@property
def template_manager(self) -> "TemplateManager":
"""Template manager associated with this engine."""
return self._template_manager
View on GitHub (pinned to f40e9a26ce)
Solutions
- Read e.message to identify the missing variable name and add it to the context
- Keep template variable contract in sync with callers; update both together
- Default optional variables in the caller (ctx.setdefault(...)) or make the template use {{ var | default(...) }} instead of bare references
- Add a render smoke-test per template with the full expected context
Example fix
# before
engine.render("summarize", {"text": doc}) # template uses {{ document }}
# after
engine.render("summarize", {"document": doc}) Defensive patterns
Strategy: try-catch
Validate before calling
from jinja2 import Environment
from jinja2.meta import find_undeclared_variables
import ast
# Inspect template source for required vars before render
src = engine.template_manager.get(name)
ast.parse("", mode="eval") if False else None
required = find_undeclared_variables(Environment().parse(src))
missing = required - set(context)
if missing:
raise KeyError(f"Missing context keys: {missing}") Type guard
def has_all_context_keys(src: str, context: dict) -> bool:
from jinja2 import Environment
from jinja2.meta import find_undeclared_variables
return not (find_undeclared_variables(Environment().parse(src)) - set(context)) Try / catch
try:
out = engine.render(name, ctx)
except KeyError as e:
if "Missing key in context" in str(e):
ctx.setdefault(str(e).split(": ")[-1], "") # or fix caller data
out = engine.render(name, ctx)
else:
raise Prevention
- Keep template variable contracts in sync with callers via tests
- Use setdefault/frozen defaults for optional context keys
- Prefer {% if var %} or |default() in templates for optional fields
When it happens
Trigger: Calling render(template_name, context) where the template references a variable (e.g. {{ document }}) that is absent from the context dict/kwargs. Adding new variables to a template without updating all callers triggers it.
Common situations: Template updated to require a new field but caller code not updated; optional context keys not defaulted; refactors renaming context keys.
Related errors
- Template '{template_name}' not found.
- Error rendering template '{template_name}': {e!s}
- Templates directory '{base_dir}' does not exist or is not a
- TemplateEngineConfig.type '{strategy}' is not registered in
- MetricsConfig.store '{strategy}' is not registered in the Me
AI-assisted analysis of microsoft/graphrag@f40e9a26ce (2026-08-27).
Data as JSON: /api/errors/fe3595200b53d72d.
Report an issue: GitHub.