666ghj/MiroFish · error · RuntimeError

Persisted Zep batch does not match the current graph input

Error message

Persisted Zep batch does not match the current graph input

What it means

RuntimeError in the graph-build resume path (backend/app/api/graph.py): when resuming an existing Zep batch the service recomputes operation_id = build_operation_id(graph_id, chunks) — a deterministic hash of graph identity plus chunk content — and compares it to project.zep_batch_operation_id persisted when the batch was created. A mismatch means the text input or chunking parameters changed between the original submission and the resume attempt, so the persisted batch belongs to different content and must not be resumed.

Source

Thrown at backend/app/api/graph.py:683

                # 分块
                task_manager.update_task(
                    task_id,
                    message=t('progress.textChunking'),
                    progress=5
                )
                chunks = TextProcessor.split_text(
                    text, 
                    chunk_size=chunk_size, 
                    overlap=chunk_overlap
                )
                builder.validate_batch_chunks(chunks, batch_size=350)
                total_chunks = len(chunks)
                
                if resume_existing_batch:
                    graph_id = project.graph_id
                    operation_id = builder.build_operation_id(graph_id, chunks)
                    if operation_id != project.zep_batch_operation_id:
                        raise RuntimeError(
                            "Persisted Zep batch does not match the current graph input"
                        )
                    submission = BatchSubmission(
                        batch_id=project.zep_batch_id,
                        operation_id=operation_id,
                        episode_uuids=[],
                        item_count=total_chunks,
                    )
                    task_manager.update_task(
                        task_id,
                        message=t('progress.waitingZepProcess'),
                        progress=55,
                    )
                else:
                    # 创建图谱
                    task_manager.update_task(
                        task_id,
                        message=t('progress.creatingZepGraph'),

View on GitHub (pinned to b5b53acc57)

Solutions

  1. Resume with the exact same document and chunk_size/chunk_overlap values used when the batch started.
  2. If the input intentionally changed, do not resume: start a fresh batch (clear zep_batch_id/zep_batch_operation_id on the project) so a new operation is created.
  3. Persist chunk_size/chunk_overlap alongside zep_batch_operation_id at submission time and reuse them on resume instead of trusting request parameters.
  4. If TextProcessor.split_text changed across versions, restart the build from scratch rather than resuming pre-upgrade batches.

Example fix

# before
if resume_existing_batch:
    graph_id = project.graph_id
    operation_id = builder.build_operation_id(graph_id, chunks)
    if operation_id != project.zep_batch_operation_id:
        raise RuntimeError("Persisted Zep batch does not match the current graph input")

# after - self-heal by abandoning the stale batch instead of hard-failing
if resume_existing_batch:
    operation_id = builder.build_operation_id(graph_id, chunks)
    if operation_id != project.zep_batch_operation_id:
        logger.warning("Stale batch %s for project %s; starting a new batch", project.zep_batch_id, project.id)
        resume_existing_batch = False  # fall through to fresh submission
        project.zep_batch_id = None
        project.zep_batch_operation_id = None
Defensive patterns

Strategy: validation

Validate before calling

if resume_existing_batch:
    stored = project.zep_batch_params  # {chunk_size, chunk_overlap, text_hash} persisted at submission
    if stored and (stored['chunk_size'] != chunk_size or stored['chunk_overlap'] != chunk_overlap):
        resume_existing_batch = False  # input changed; start a new batch

Try / catch

try:
    _resume_or_submit(resume_existing_batch)
except RuntimeError as e:
    if 'does not match the current graph input' in str(e):
        project.zep_batch_id = None
        project.zep_batch_operation_id = None
        _resume_or_submit(resume_existing_batch=False)
    else:
        raise

Prevention

When it happens

Trigger: Resuming a build with resume_existing_batch=true after: the source document was re-uploaded or edited; chunk_size/chunk_overlap changed in the request; the project's text preprocessing produced different chunks (TextProcessor behavior change between versions); or graph_id changed but the old zep_batch_operation_id row survived.

Common situations: User pauses a long build, edits the document, and hits resume; deployment upgrades the text splitter mid-batch; two tabs building the same project with different chunk settings overwrite each other's state.

Related errors


AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14). Data as JSON: /api/errors/6ebe233fc512b74f. Report an issue: GitHub.