666ghj/MiroFish · error · RuntimeError
Zep batch {submission.batch_id} returned an incomplete item
Error message
Zep batch {submission.batch_id} returned an incomplete item What it means
Raised by GraphBuilder._wait_for_batch while validating each item of a succeeded batch: after sorting items by sequence_index, any item whose status is not exactly 'succeeded', or whose episode_uuid is missing/empty, triggers this RuntimeError. Even though the batch overall reported success, at least one item did not produce a usable episode reference, so the pipeline refuses to return a partial UUID list.
Source
Thrown at backend/app/services/graph_builder.py:700
f"failed_items={len(failed_items)}; first_error={first_error}"
)
if len(items) != submission.item_count:
raise RuntimeError(
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_uuidsView on GitHub (pinned to b5b53acc57)
Solutions
- List the batch items manually and inspect the offending item's status/error fields to learn why Zep did not fully succeed it.
- Filter out empty or whitespace-only chunks before submission — they are the most common cause of per-item skips.
- Upgrade the zep-cloud SDK if attribute names drifted; the code reads episode_uuid via getattr and None fails the check.
- Resubmit only the incomplete items as a fresh batch and merge the resulting UUID lists.
Example fix
# before chunks = raw_chunks # after chunks = [c.strip() for c in raw_chunks] chunks = [c for c in chunks if c]
Defensive patterns
Strategy: validation
Validate before calling
chunks = [c for c in (c.strip() for c in chunks) if c] # drop empty/blank chunks that Zep skips
Try / catch
try:
uuids = builder._wait_for_batch(submission)
except RuntimeError as e:
if 'incomplete item' in str(e):
bad = [i for i in builder._list_batch_items(submission.batch_id)
if getattr(i, 'status', None) != 'succeeded' or not getattr(i, 'episode_uuid', None)]
resubmit([original_chunk_for(i) for i in bad])
else:
raise Prevention
- Strip and filter empty chunks before submission.
- Keep a mapping from sequence_index to source chunk so failed items can be resubmitted individually.
- Keep the zep-cloud SDK current so item attributes parse as expected.
When it happens
Trigger: A batch item whose status is 'skipped' or another non-succeeded value at item level (note: 'skipped' is tolerated in the count check of error 23 but NOT here), or an item that succeeded but Zep returned no episode_uuid attribute. Usually a handful of items in an otherwise green batch.
Common situations: Zep skipping items it considers duplicates or empty while still marking the batch 'succeeded'; SDK version returning episode_uuid under a different attribute name; items with blank/degenerate text that Zep processes to nothing.
Related errors
- Zep batch item exceeds 10,000 characters at chunk {oversized
- Zep batch {submission.batch_id} did not finish within {timeo
- Zep batch {submission.batch_id} ended as {status}; failed_it
- Zep batch {submission.batch_id} contains {len(items)} items,
- graph_id is required
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/8239800079091c30.
Report an issue: GitHub.