666ghj/MiroFish · error · RuntimeError
Zep batch {batch_id} processing is unconfirmed
Error message
Zep batch {batch_id} processing is unconfirmed What it means
RuntimeError at the end of submit_document_batch: client.batch.process(batch_id) raised, and since a process POST can succeed server-side while the response is lost, the code reconciles with a safe GET (batch.get with read retry). If the fetched status is None or 'draft', the batch was never actually queued for processing — all items were submitted but processing is unconfirmed, and re-POSTing process is deliberately avoided (the comment notes a second POST is unsafe).
Source
Thrown at backend/app/services/graph_builder.py:555
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"}:
raise RuntimeError(
f"Zep batch {batch_id} processing is unconfirmed"
) from error
return BatchSubmission(
batch_id=batch_id,
operation_id=operation_id,
episode_uuids=episode_uuids,
item_count=total_chunks,
)
@staticmethod
def validate_batch_chunks(chunks: List[str], *, batch_size: int = 350) -> None:
"""Validate every Batch API limit before the first Cloud mutation."""
if not chunks:
raise ValueError("At least one text chunk is required")
if not 1 <= batch_size <= 350:
raise ValueError("batch_size must be between 1 and 350")View on GitHub (pinned to b5b53acc57)
Solutions
- Manually trigger processing once in the Zep console (or via a single careful re-POST) and confirm status leaves draft, then resume the build.
- If status was merely lagging, retry the build/resume flow after a short wait — the GET will then show processing/processed.
- Raise the client timeout for the process call and lengthen read-retry patience in call_zep_read_with_retry.
- Check network intermediaries (nginx, service mesh) for idle timeouts that kill the long process response.
Example fix
# before
except Exception as error:
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"}:
raise RuntimeError(f"Zep batch {batch_id} processing is unconfirmed") from error
# after - poll the GET briefly before declaring unconfirmed, include status
except Exception as error:
for delay in (1, 3, 5):
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) not in {None, "draft"}:
break
time.sleep(delay)
else:
raise RuntimeError(
f"Zep batch {batch_id} processing is unconfirmed (status={getattr(summary, 'status', None)!r}); "
"trigger processing once via the Zep console, then resume"
) from error Defensive patterns
Strategy: retry
Try / catch
try:
submission = builder.submit_document_batch(graph_id, chunks, batch_size=bs)
except RuntimeError as e:
if 'processing is unconfirmed' in str(e):
summary = call_zep_read_with_retry(lambda: builder.client.batch.get(batch_id=project.zep_batch_id), operation_name='recheck')
if getattr(summary, 'status', None) in {None, 'draft'}:
raise # operator must trigger process once in Zep console, then resume
submission = BatchSubmission(batch_id=project.zep_batch_id, operation_id=project.zep_batch_operation_id, episode_uuids=[], item_count=len(chunks))
else:
raise Prevention
- Set generous timeouts on the batch.process call — its response can be slow and loss is costly.
- After any process failure, always reconcile with a GET (never a second process POST) before deciding.
- Persist batch identity so an unconfirmed process can be finished manually in the Zep console and the build resumed.
- Exclude Zep API calls from gateway idle timeouts in the deployment config.
When it happens
Trigger: process() times out or hits a retryable network error; Zep accepted items but the process trigger never landed, leaving status='draft'; Zep Cloud incident where both POST and GET degrade.
Common situations: Long-running builds whose final process call crosses a proxy/gateway timeout; transient 5xx from Zep; the GET reconcile racing Zep's own state update so status still reads draft.
Related errors
- Zep batch creation is unconfirmed and no matching operation
- Persisted Zep batch does not match the current graph input
- Multiple Zep batches match operation {operation_id}; refusin
- Zep Batch API returned no batch_id
- Zep batch {batch_id} item submission is unconfirmed; the dra
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/acca4d000fa0e2b8.
Report an issue: GitHub.