wavetermdev/waveterm · error

error flushing cache entry[%v]: %v

Error message

error flushing cache entry[%v]: %v

What it means

During FlushCache, a per-entry flush (writing a dirty cache entry's parts/metadata to the DB) failed for a specific key. FlushCache wraps the underlying error with the entry key so the caller knows which file entry failed; entries flushed before the failure still count in stats.NumCommitted.

Source

Thrown at pkg/filestore/blockstore.go:419

	defer s.setIsFlushing(false)
	startTime := time.Now()
	defer func() {
		stats.FlushDuration = time.Since(startTime)
	}()

	// get a copy of dirty keys so we can iterate without the lock
	dirtyCacheKeys := s.getDirtyCacheKeys()
	stats.NumDirtyEntries = len(dirtyCacheKeys)
	for _, key := range dirtyCacheKeys {
		err := withLock(s, key.ZoneId, key.Name, func(entry *CacheEntry) error {
			return entry.flushToDB(ctx, false)
		})
		if ctx.Err() != nil {
			// transient error (also must stop the loop)
			return stats, ctx.Err()
		}
		if err != nil {
			return stats, fmt.Errorf("error flushing cache entry[%v]: %v", key, err)
		}
		stats.NumCommitted++
	}
	return stats, nil
}

///////////////////////////////////

func (f *WaveFile) partIdxAtOffset(offset int64) int {
	partIdx := int(offset / partDataSize)
	if f.Opts.Circular {
		maxPart := int(f.Opts.MaxSize / partDataSize)
		partIdx = partIdx % maxPart
	}
	return partIdx
}

func incompletePartsFromMap(partMap map[int]int) []int {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped cause (%v of the inner error) to find the real failure (DB connectivity, permissions, etc.).
  2. Retry FlushCache once the underlying DB issue is fixed; unflushed entries remain dirty and will be retried.
  3. Check ctx.Err() to distinguish transient cancellation from a persistent DB error.

Example fix

// before
stats, err := fs.FlushCache(ctx)
if err != nil { log.Fatal(err) }
// after
stats, err := fs.FlushCache(ctx)
if err != nil {
    log.Printf("partial flush committed=%d, err=%v; retrying", stats.NumCommitted, err)
    time.Sleep(time.Second)
    _, err = fs.FlushCache(ctx)
}
Defensive patterns

Strategy: retry

Try / catch

stats, err := fs.FlushCache(ctx)
if err != nil {
    log.Printf("flush failed after %d entries: %v", stats.NumCommitted, err)
    if ctx.Err() == nil { // not canceled: worth retrying
        time.Sleep(time.Second)
        _, err = fs.FlushCache(ctx)
    }
}

Prevention

When it happens

Trigger: Any underlying error from flushing a single cache entry during FlushCache — DB write failures, context cancellation on the entry's operation, corrupted part data — surfaced as 'error flushing cache entry[zone:name]: <cause>'.

Common situations: Database unavailable or read-only during a flush; a large flush racing a shutdown so entries get canceled contexts; disk/DB quota issues while persisting data parts.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/89b3d614a5f6bde3. Report an issue: GitHub.