666ghj/MiroFish · error · RuntimeError
Zep batch {batch_id} acknowledged {len(item_details or [])}
Error message
Zep batch {batch_id} acknowledged {len(item_details or [])} of {len(items)} items What it means
RuntimeError in submit_document_batch: after adding a group of items, the count of acknowledged item_details does not match len(items), so the code reconciles via _reconcile_batch_item_count and re-checks sequence_index completeness. If the reconciled list still is not exactly expected_item_count items with indexes range(expected_item_count), Zep acknowledged fewer items than were submitted and the mismatch is unrecoverable — proceeding would silently drop graph episodes.
Source
Thrown at backend/app/services/graph_builder.py:536
f"Zep batch {batch_id} item submission failed"
) from e
if len(item_details or []) != len(items):
recovered_items = self._reconcile_batch_item_count(
batch_id,
expected_item_count,
)
recovered_indexes = {
getattr(item, "sequence_index", None)
for item in recovered_items
}
if (
len(recovered_items) == expected_item_count
and recovered_indexes == set(range(expected_item_count))
):
item_details = recovered_items[i:expected_item_count]
else:
raise RuntimeError(
f"Zep batch {batch_id} acknowledged {len(item_details or [])} "
f"of {len(items)} items"
)
for item in item_details:
episode_uuid = getattr(item, "episode_uuid", None)
if episode_uuid:
episode_uuids.append(episode_uuid)
try:
self.client.batch.process(batch_id=batch_id)
except Exception as error:
# A process response can be lost after the server accepted it.
# Reconcile with a safe GET instead of issuing a second POST.
summary = call_zep_read_with_retry(
lambda: self.client.batch.get(batch_id=batch_id),
operation_name=f"reconcile batch {batch_id}",
)
if getattr(summary, "status", None) in {None, "draft"}:View on GitHub (pinned to b5b53acc57)
Solutions
- Retry via the resume flow once backend/Zep recovers — the persisted batch identity supports it.
- Inspect the batch items in the Zep console and identify which sequence indexes are missing; if unrecoverable, delete the draft batch and rebuild.
- Ensure only one worker processes a given operation at a time (per-project submission lock) so counts are not skewed by concurrency.
- Lower batch_size to reduce per-request item counts if truncation recurs.
- Report to Zep if add consistently acknowledges fewer items than sent with a 2xx.
Example fix
# before
else:
raise RuntimeError(
f"Zep batch {batch_id} acknowledged {len(item_details or [])} of {len(items)} items"
)
# after - name the missing indexes so operators can repair precisely
else:
acked = {getattr(it, "sequence_index", None) for it in (item_details or [])}
missing = sorted(set(range(expected_item_count)) - acked)
raise RuntimeError(
f"Zep batch {batch_id} acknowledged {len(item_details or [])} of {len(items)} items "
f"(missing sequence indexes: {missing[:20]}{'...' if len(missing) > 20 else ''})"
) Defensive patterns
Strategy: validation
Validate before calling
expected = len(items)
recovered = builder._reconcile_batch_item_count(batch_id, expected)
indexes = {getattr(it, 'sequence_index', None) for it in recovered}
if not (len(recovered) == expected and indexes == set(range(expected))):
raise RuntimeError(f'Batch {batch_id} incomplete; missing {sorted(set(range(expected)) - indexes)}') Try / catch
try:
submission = builder.submit_document_batch(graph_id, chunks, batch_size=bs)
except RuntimeError as e:
if 'acknowledged' in str(e) and 'of' in str(e):
# item set is provably incomplete; delete the draft batch and rebuild rather than resume
logger.error('Incomplete batch acknowledgment: %s', str(e))
raise
raise Prevention
- Enforce single-writer per batch (per-project lock) so counts are not skewed by concurrency.
- Check acknowledged-vs-submitted counts after every add group, as this code does, and reconcile immediately.
- Keep batch_size well under 350 when Zep is under load to reduce truncation risk.
- If a batch is incomplete, delete the draft and restart instead of layering a second partial submission.
When it happens
Trigger: batch.add returns item_details for only part of the submitted group (server truncation or partial acceptance); the reconcile listing shows missing sequence indexes, meaning some chunks never landed; concurrent item additions to the same batch from another process skewing counts.
Common situations: Large batch groups near the 350-item limit under load; Zep Cloud eventually-consistent listing returning partial item sets; two workers resuming the same batch simultaneously.
Related errors
- Persisted Zep batch does not match the current graph input
- Zep batch {batch_id} item submission is unconfirmed; the dra
- Multiple Zep batches match operation {operation_id}; refusin
- Zep batch creation is unconfirmed and no matching operation
- Zep Batch API returned no batch_id
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/16c6aad4bf509728.
Report an issue: GitHub.