langchain-ai/deepagents · error · RuntimeError
Failed to parse hook interrupt
Error message
Failed to parse hook interrupt
What it means
After obtaining a runtime, fulfill_interrupt calls fulfill_hook_interrupt, which returns None when the interrupt payload cannot be parsed as a Hooks v2 hook invocation (not a valid HookInvocationResponse shape / fails identity validation). The manager converts that None into a RuntimeError so callers get a clear failure instead of an opaque downstream error.
Source
Thrown at libs/code/deepagents_code/hooks/manager.py:541
payload: Raw LangGraph interrupt value.
Returns:
Resume value for `Command(resume=...)`.
Raises:
RuntimeError: If hooks are unavailable, or the payload is not a
parseable hook invocation.
"""
from deepagents_code.hooks.client import fulfill_hook_interrupt
runtime = self._runtime
if runtime is None:
msg = "Received hook invocation interrupt without a HooksRuntime"
raise RuntimeError(msg)
resume = await fulfill_hook_interrupt(runtime, payload)
if resume is None:
msg = "Failed to parse hook interrupt"
raise RuntimeError(msg)
return resume
async def fulfill_pending_interrupts(
self,
pending: Mapping[str, object],
) -> dict[str, dict[str, object]]:
"""Execute a batch of server-owned hook interrupts.
Args:
pending: LangGraph interrupt id to raw interrupt payload.
Returns:
Resume values keyed by interrupt id.
Raises:
RuntimeError: If hooks are unavailable, or a payload is not a
parseable hook invocation.
"""View on GitHub (pinned to a1af029e6e)
Solutions
- Log and inspect the raw payload; confirm it matches the Hooks v2 invocation interrupt shape (use is_hook_interrupt_payload to pre-check)
- Re-fetch the payload from the pending interrupts map rather than reconstructing it manually
- If the payload came from an older version, migrate or regenerate the interrupt instead of resuming it directly
- Wrap fulfillment and surface the payload id in your own error handling to aid diagnosis
Example fix
// before
await manager.fulfill_interrupt(interrupt_data) # unvalidated
// after
from deepagents_code.hooks.interrupt import is_hook_interrupt_payload
if is_hook_interrupt_payload(interrupt_data):
await manager.fulfill_interrupt(interrupt_data)
else:
raise ValueError(f"Not a hook interrupt payload: {interrupt_data!r}") Defensive patterns
Strategy: validation
Validate before calling
from deepagents_code.hooks.interrupt import is_hook_interrupt_payload
if not is_hook_interrupt_payload(payload):
raise ValueError("interrupt is not a Hooks v2 invocation payload")
Type guard
def is_valid_hook_interrupt(payload: object) -> bool:
from deepagents_code.hooks.interrupt import is_hook_interrupt_payload
return isinstance(payload, dict) and is_hook_interrupt_payload(payload)
Try / catch
try:
resume = await manager.fulfill_interrupt(payload)
except RuntimeError as exc:
if "Failed to parse hook interrupt" in str(exc):
logger.error("unparseable hook payload: %r", payload)
resume = None # skip or regenerate the interrupt
else:
raise
Prevention
- Pre-check payloads with is_hook_interrupt_payload before fulfilling
- Never hand-edit or manually reconstruct interrupt payloads
- Regenerate interrupts from persisted state when upgrading across Hooks versions
When it happens
Trigger: Passing an interrupt payload to fulfill_interrupt that is not a well-formed hook invocation payload — wrong keys, missing invocation_id/snapshot_id, or a payload that fails parse_hook_resume_value validation (see the id-mismatch errors).
Common situations: Manually constructed or hand-edited interrupt payloads; payloads from an older Hooks version parsed with a newer adapter; grabbing an interrupt from graph state that is actually a different interrupt type (tool approval, not a hook).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Permission interrupted by hook
- Hook resume invocation_id mismatch: expected {invocation_id}
- Hook resume snapshot_id mismatch: expected {snapshot_id}, go
- Received hook invocation interrupt without a HooksRuntime
- -32600
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/51eebc8b4abc8ee0.
Report an issue: GitHub.