langchain-ai/deepagents · error · ValueError
Hook resume invocation_id mismatch: expected {invocation_id}
Error message
Hook resume invocation_id mismatch: expected {invocation_id}, got {response.invocation_id} What it means
parse_hook_resume_value validates that a hook resume payload (submitted when the user resolves a hook interrupt) carries the same invocation_id as the suspended invocation. The pydantic HOOK_INVOCATION_RESPONSE_ADAPTER first parses the raw value; then this check ensures the response corresponds to the invocation being resumed. A mismatch means the resume value belongs to a different hook invocation and is rejected with ValueError.
Source
Thrown at libs/code/deepagents_code/hooks/interrupt.py:107
Args:
value: Resume payload returned by the client.
invocation_id: Expected invocation id from the request.
snapshot_id: Expected configuration snapshot id.
Returns:
Validated response.
Raises:
ValueError: If the resume payload is missing, mistyped, or mismatched.
"""
response = HOOK_INVOCATION_RESPONSE_ADAPTER.validate_python(value)
if response.invocation_id != invocation_id:
msg = (
f"Hook resume invocation_id mismatch: expected {invocation_id}, "
f"got {response.invocation_id}"
)
raise ValueError(msg)
if response.snapshot_id != snapshot_id:
msg = (
f"Hook resume snapshot_id mismatch: expected {snapshot_id}, "
f"got {response.snapshot_id}"
)
raise ValueError(msg)
return response
def is_hook_interrupt_payload(value: object) -> bool:
"""Return whether `value` looks like a Hooks v2 invocation interrupt."""
return (
isinstance(value, dict) and value.get("type") == HOOK_INVOCATION_INTERRUPT_TYPE
)
View on GitHub (pinned to a1af029e6e)
Solutions
- Re-read the pending interrupt payload and resume with its exact invocation_id (and snapshot_id)
- Discard stale resume values and re-request the interrupt — the old invocation_id is no longer valid
- If multiple interrupts are pending, key resume payloads by interrupt id so the right value reaches the right invocation
- Check for framework updates if interrupt IDs are regenerated on retry, and upgrade to a version that preserves them
Example fix
// before resume_value = saved_resume # from an earlier session result = parse_hook_resume_value(saved_resume, expected_invocation_id, snapshot_id) // after pending = engine.get_pending_interrupts()[expected_invocation_id] resume_value = pending.build_resume(user_input) result = parse_hook_resume_value(resume_value, expected_invocation_id, snapshot_id)
Defensive patterns
Strategy: validation
Validate before calling
from deepagents_code.hooks.interrupt import parse_hook_resume_value
# verify pairing before resuming
if resume_payload.get("invocation_id") != expected_invocation_id:
raise ValueError("stale resume payload: refetch pending interrupt")
Type guard
def matches_invocation(payload: dict, invocation_id: str) -> bool:
return payload.get("invocation_id") == invocation_id
Try / catch
try:
resume = parse_hook_resume_value(payload, invocation_id, snapshot_id)
except ValueError as exc:
logger.error("hook resume rejected: %s", exc)
resume = refetch_and_resume(invocation_id) # re-answer the fresh interrupt
Prevention
- Always resume from the payload currently stored in the pending-interrupts map
- Never cache resume values across graph re-invocations or sessions
- Key stored resume values by invocation_id to avoid cross-pairing multiple pending hooks
When it happens
Trigger: Resuming a hook interrupt via _invoke_hook/parse_hook_resume_value with a payload whose invocation_id differs from the expected one — e.g. resuming an old interrupt after the agent re-issued a new hook invocation, or mixing up interrupt IDs when several hooks are pending.
Common situations: Stale UI state in the coding agent (TUI) submitting an outdated resume after re-render; manually replaying saved resume payloads across sessions; concurrent hook interrupts where the caller pairs the wrong payload with the wrong invocation.
Related errors
- Hook resume snapshot_id mismatch: expected {snapshot_id}, go
- Permission interrupted by hook
- Received hook invocation interrupt without a HooksRuntime
- Failed to parse hook interrupt
- -32600
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/e31a26f6219ff116.
Report an issue: GitHub.