fix(checkpoint/memory): warn on broken diff chain, guard against cycles

- Add logger.warning when a mid-chain blob is missing (fixes silent truncation bug)
- Add cycle guard to prevent infinite loops on corrupt blob stores
- Fix type annotation on diff_channels from dict[str, Any] to dict[str, str]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sydney Runkle
2026-04-17 14:54:58 -04:00
co-authored by Claude Sonnet 4.6
parent d76127fbbf
commit 1cb057e6bc
@@ -126,7 +126,7 @@ class InMemorySaver(
from langgraph.checkpoint.base import DiffChainValue
channel_values: dict[str, Any] = {}
diff_channels: dict[str, Any] = {}
diff_channels: dict[str, str] = {}
for k, v in versions.items():
kk = (thread_id, checkpoint_ns, k, v)
@@ -142,9 +142,24 @@ class InMemorySaver(
chain_deltas: list[list[Any]] = []
base: list[Any] | None = None
version: str | None = current_version
visited: set[str] = set()
while version is not None:
if version in visited:
logger.warning(
"DiffChannel chain cycle detected at version %r for channel %r; breaking",
version,
k,
)
break
visited.add(version)
kk = (thread_id, checkpoint_ns, k, version)
if kk not in self.blobs:
logger.warning(
"DiffChannel chain is broken: blob for channel %r version %r not found; "
"partial history will be returned",
k,
version,
)
break
vv = self.blobs[kk]
if vv[0] == "diff":