python/cpython · error · RuntimeError
annotate function does not support VALUE format
Error message
annotate function does not support VALUE format
What it means
Inside call_annotate_function's VALUE branch, an annotate function that raised NotImplementedError for Format.VALUE violates the PEP 649 contract (annotate functions must support VALUE). The code marks this 'should be impossible' and raises RuntimeError, signaling a broken or hand-crafted __annotate__ rather than caller error.
Source
Thrown at Lib/annotationlib.py:846
globals.transmogrify(cell_dict)
if _is_evaluate:
if isinstance(result, ForwardRef):
return result.evaluate(format=Format.FORWARDREF)
else:
return result
else:
return {
key: (
val.evaluate(format=Format.FORWARDREF)
if isinstance(val, ForwardRef)
else val
)
for key, val in result.items()
}
elif format == Format.VALUE:
# Should be impossible because __annotate__ functions must not raise
# NotImplementedError for this format.
raise RuntimeError("annotate function does not support VALUE format")
else:
raise ValueError(f"Invalid format: {format!r}")
def _build_closure(annotate, owner, is_class, stringifier_dict, *, allow_evaluation):
if not annotate.__closure__:
return None, None
new_closure = []
cell_dict = {}
for name, cell in zip(annotate.__code__.co_freevars, annotate.__closure__, strict=True):
cell_dict[name] = cell
new_cell = None
if allow_evaluation:
try:
cell.cell_contents
except ValueError:
pass
else:View on GitHub (pinned to bc6749cc3b)
Solutions
- Fix the custom __annotate__ so it returns a dict for Format.VALUE (it may special-case STRING/FORWARDREF but must handle VALUE).
- If you cannot support annotation at all, set __annotate__ to None / delete it instead of raising.
- Catch RuntimeError defensively when introspecting third-party objects you do not control.
Example fix
# before
def __annotate__(format):
raise NotImplementedError # breaks contract -> RuntimeError from call_annotate_function
# after
def __annotate__(format):
return {'x': int} Defensive patterns
Strategy: try-catch
Validate before calling
def annotate_supports_value(annotate) -> bool:
try:
return isinstance(annotate(1), dict) # 1 == Format.VALUE value if stable; prefer Format.VALUE
except NotImplementedError:
return False
except Exception:
return False Type guard
def has_sane_annotate(obj) -> bool:
ann = getattr(obj, '__annotate__', None)
if ann is None:
return True # no custom implementation, nothing to violate
try:
from annotationlib import Format
return isinstance(ann(Format.VALUE), dict)
except (NotImplementedError, TypeError, ValueError):
return False Try / catch
try:
ann = annotationlib.get_annotations(obj, format=Format.VALUE)
except RuntimeError as e:
if 'does not support VALUE' in str(e):
ann = {} # object has a broken __annotate__; degrade gracefully
else:
raise Prevention
- Custom __annotate__ must return a dict for every format, especially VALUE
- Do not make __annotate__ raise NotImplementedError unconditionally
- Test custom __annotate__ against all public formats
When it happens
Trigger: Attaching a custom __annotate__ that raises NotImplementedError unconditionally or for Format.VALUE; objects built by metaclasses or decorators that synthesize __annotate__ incorrectly; mocks/stubs that raise NotImplementedError for all calls.
Common situations: Test doubles or protocol implementations where every method raises NotImplementedError; decorator libraries fabricating __annotate__ to opt out of annotations; bugs in code generators that emit __annotate__ functions.
Related errors
- {obj!r}.__annotate__ returned a non-dict
- Cannot stringify annotation containing string formatting
- The VALUE_WITH_FAKE_GLOBALS format is for internal use only
- self.raw should implement RawIOBase: it should not raise Blo
- write() returned incorrect number of bytes
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/84aca518e8fb9116.
Report an issue: GitHub.