666ghj/MiroFish · error · RuntimeError
Zep batch {submission.batch_id} returned mismatched episode
Error message
Zep batch {submission.batch_id} returned mismatched episode UUIDs What it means
Raised by GraphBuilder._wait_for_batch during per-item validation: for a succeeded item that has a source_uuid, that source_uuid must equal the item's episode_uuid. Zep echoes back the client-supplied source UUID; a mismatch means the server re-associated the item with a different episode than the one the client declared (e.g. dedup merged it into an existing episode), which would corrupt the builder's UUID bookkeeping.
Source
Thrown at backend/app/services/graph_builder.py:704
f"Zep batch {submission.batch_id} contains {len(items)} items, "
f"expected {submission.item_count}"
)
ordered_items = sorted(
items,
key=lambda item: getattr(item, "sequence_index", 0) or 0,
)
episode_uuids: List[str] = []
for item in ordered_items:
item_status = getattr(item, "status", None)
episode_uuid = getattr(item, "episode_uuid", None)
source_uuid = getattr(item, "source_uuid", None)
if item_status != "succeeded" or not episode_uuid:
raise RuntimeError(
f"Zep batch {submission.batch_id} returned an incomplete item"
)
if source_uuid and source_uuid != episode_uuid:
raise RuntimeError(
f"Zep batch {submission.batch_id} returned mismatched episode UUIDs"
)
episode_uuids.append(episode_uuid)
if progress_callback:
progress_callback(
t(
'progress.processingComplete',
completed=len(episode_uuids),
total=submission.item_count,
),
1.0,
)
return episode_uuids
def _wait_for_episodes(
self,
episode_uuids: List[str],View on GitHub (pinned to b5b53acc57)
Solutions
- Use a fresh graph (new graph_id) for a full rebuild instead of re-ingesting into the existing one.
- Regenerate unique source_uuid values (e.g. uuid4-derived, content-hash + run-id) for every retry so dedup cannot merge across runs.
- Before resubmitting, search the graph (client.graph.episode/search) for the source_uuid to check whether it already exists.
- If Zep should never merge, review whether your plan/config enables dedup and disable it for this workflow.
Example fix
# before
source_uuid = content_hash # stable across runs -> dedup merges
# after
import uuid
source_uuid = f'{run_id}:{content_hash}' # unique per run Defensive patterns
Strategy: validation
Validate before calling
def make_source_uuid(run_id: str, content_hash: str) -> str:
return f'{run_id}:{content_hash}' # unique per ingestion run, dedup-proof Try / catch
try:
uuids = builder._wait_for_batch(submission)
except RuntimeError as e:
if 'mismatched episode UUIDs' in str(e):
# episodes were deduped onto an existing graph; rebuild into a fresh graph_id
raise RuntimeError('re-ingest into a new graph or regenerate source UUIDs') from e
raise Prevention
- Use a new graph_id for full rebuilds.
- Make source_uuid unique per run (run-id + content hash), never a bare stable hash.
- Before re-ingesting, search the graph for existing source UUIDs.
When it happens
Trigger: Submitting items with explicit source_uuid values that collide with already-ingested episodes in the same graph, so Zep deduplicates/merges them into an existing episode and returns a different episode_uuid; or re-running ingestion of the same content into the same graph-id combination twice.
Common situations: Rebuilding a graph without a new graph-id, so previous episodes exist and Zep dedupes new items onto them; retrying a partially failed ingestion run with the same source UUIDs; switching a project between shared and per-project graphs while reusing source UUIDs.
Related errors
- Zep batch {submission.batch_id} contains {len(items)} items,
- Persisted Zep batch does not match the current graph input
- Zep batch {batch_id} acknowledged {len(item_details or [])}
- Zep batch item exceeds 10,000 characters at chunk {oversized
- Zep batch {batch_id} item cursor did not advance
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/85e767f5e5f5fbba.
Report an issue: GitHub.