666ghj/MiroFish · error · RuntimeError
Zep Batch API returned no batch_id
Error message
Zep Batch API returned no batch_id
What it means
RuntimeError in submit_document_batch: a batch object came back from create (or from reconcile) but getattr(batch, 'batch_id', None) is empty — the Zep Batch API response lacks the batch identifier this code depends on for every subsequent call (add items, process, get). Without a batch_id the operation cannot proceed and, importantly, the batch_created_callback(batch_id, ...) journaling would persist a useless identity, so it aborts first.
Source
Thrown at backend/app/services/graph_builder.py:453
try:
batch = self.client.batch.create(
metadata={
"mirofish_operation_id": operation_id,
"graph_id": graph_id,
"chunk_count": total_chunks,
}
)
except Exception as error:
if not is_retryable_zep_error(error):
raise
batch = self._find_batch_by_operation_id(graph_id, operation_id)
if batch is None:
raise RuntimeError(
"Zep batch creation is unconfirmed and no matching operation was found"
) from error
batch_id = getattr(batch, "batch_id", None)
if not batch_id:
raise RuntimeError("Zep Batch API returned no batch_id")
if batch_created_callback:
batch_created_callback(batch_id, operation_id)
episode_uuids: List[str] = []
for i in range(0, total_chunks, batch_size):
batch_chunks = chunks[i:i + batch_size]
batch_num = i // batch_size + 1
total_batches = (total_chunks + batch_size - 1) // batch_size
if progress_callback:
progress = (i + len(batch_chunks)) / total_chunks
progress_callback(
t('progress.sendingBatch', current=batch_num, total=total_batches, chunks=len(batch_chunks)),
progress
)
items = [
BatchAddItem(View on GitHub (pinned to b5b53acc57)
Solutions
- Log the full batch object when this fires to see the actual response shape.
- Pin or upgrade the Zep SDK to the version this service was written against, and re-check the batch-create response schema.
- If the field was renamed, read it with a fallback: batch_id = getattr(batch, 'batch_id', None) or getattr(batch, 'id', None).
- Because the batch may exist server-side, look it up by mirofish_operation_id in the Zep console and clean up or resume manually.
- In tests, make mocked batches include a realistic batch_id.
Example fix
# before
batch_id = getattr(batch, "batch_id", None)
if not batch_id:
raise RuntimeError("Zep Batch API returned no batch_id")
# after - tolerate schema rename, keep the hard failure for true emptiness
batch_id = (
getattr(batch, "batch_id", None)
or getattr(batch, "id", None)
)
if not batch_id:
raise RuntimeError(
f"Zep Batch API returned no batch_id (response type={type(batch).__name__}, "
f"fields={getattr(batch, 'model_fields', None) or vars(getattr(batch, '__dict__', {}))}"
) Defensive patterns
Strategy: type-guard
Type guard
def has_batch_id(batch) -> bool:
return bool(getattr(batch, 'batch_id', None) or getattr(batch, 'id', None)) Try / catch
try:
submission = builder.submit_document_batch(graph_id, chunks, batch_size=bs)
except RuntimeError as e:
if 'no batch_id' in str(e):
# batch may exist server-side; find it by mirofish_operation_id before any retry
logger.error('Batch create returned no id; reconcile by operation metadata: %s', str(e))
raise
raise Prevention
- Pin the Zep SDK version and re-verify the batch-create response schema after upgrades.
- Log the raw batch object when the id is missing to catch schema renames immediately.
- In tests, always give mocked batches a realistic batch_id.
- If a batch was created without a captured id, reconcile by mirofish_operation_id metadata instead of re-creating.
When it happens
Trigger: Zep SDK version change renaming the field (e.g. id instead of batch_id) so getattr misses it; a degenerate response object (empty model) returned during a partial outage; the reconcile path matched a batch stub without an id.
Common situations: Upgrading the zep-python SDK to a version with a different response schema; server error pages deserialized into empty objects; mocking in tests that returns a batch without batch_id.
Related errors
- Persisted Zep batch does not match the current graph input
- Multiple Zep batches match operation {operation_id}; refusin
- Zep batch creation is unconfirmed and no matching operation
- Zep batch {batch_id} item submission is unconfirmed; the dra
- Zep batch {batch_id} item submission failed
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/754190bb81595ded.
Report an issue: GitHub.