weaviate/weaviate · error

no export prepared

Error message

no export prepared

What it means

Commit's critical section found p.preparedReq nil even though activeExport still matches. This means the prepared-request slot was cleared (by a timeout callback, Abort, or a prior Commit) while the activeExport marker was not yet reset — an inconsistent intermediate state caught defensively before dereferencing preparedReq.

Source

Thrown at usecases/export/participant.go:330

				p.clearAndRelease()
			}
			p.mu.Unlock()
		}()

		timer := p.abortTimer
		if timer == nil {
			errRet = fmt.Errorf("timer is nil. No export prepared")
			return errRet
		}
		timer.Stop()

		if p.activeExport != exportID {
			errRet = fmt.Errorf("active export ID mismatch: expected %q, got %q", p.activeExport, exportID)
			return errRet
		}

		if p.preparedReq == nil {
			errRet = fmt.Errorf("no export prepared")
			return errRet
		}
		if p.preparedReq.ID != exportID {
			errRet = fmt.Errorf("export ID mismatch: expected %q, got %q", p.preparedReq.ID, exportID)
			return errRet
		}
		// Pointer identity check: if an Abort cleared the slot and a new
		// Prepare set a different *ExportRequest (possibly with the same
		// export ID) while we were doing backend I/O outside the lock,
		// the pointer will differ even though the ID matches. This is a
		// defense-in-depth guard — the coordinator prevents ID reuse via
		// checkIfExportExists, so this race cannot happen in practice.
		if p.preparedReq != req {
			errRet = fmt.Errorf("export request was replaced during backend initialization (abort+re-prepare race)")
			return errRet
		}

		if backendStore == nil {

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Restart the export lifecycle with a new Prepare — the reservation is gone and cannot be recovered.
  2. Check for concurrent Abort/timeout activity during Commit; serialize operations on the participant.
  3. Shorten work performed between the unlocked state peek and Commit's critical section.

Example fix

// before
// concurrent Abort clears preparedReq mid-Commit -> "no export prepared"
go participant.Abort(id)
err := participant.Commit(ctx, id)
// after
// serialize lifecycle calls
mu.Lock()
err := participant.Commit(ctx, id)
mu.Unlock()
Defensive patterns

Strategy: retry

Validate before calling

// do not call Abort concurrently with Commit for the same ID
// (serialize lifecycle calls with your own mutex)

Try / catch

if err := participant.Commit(ctx, id); err != nil {
    if strings.Contains(err.Error(), "no export prepared") {
        return retryWithFreshPrepare(ctx) // slot cleared; fresh lifecycle required
    }
    return err
}

Prevention

When it happens

Trigger: The abortTimer callback ran clearAndRelease concurrently; a previous Commit attempt errored after nil-ing preparedReq; Abort racing Commit between the unlocked peek and the locked critical section.

Common situations: Slow snapshot waits or backend initialization widening the race window; tests killing timers or forcing timeouts.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/0c16f5c255724a19. Report an issue: GitHub.