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
- Inspect the wrapped cause (%v of the inner error) to find the real failure (DB connectivity, permissions, etc.).
- Retry FlushCache once the underlying DB issue is fixed; unflushed entries remain dirty and will be retried.
- 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
- Monitor DB health before triggering large flushes.
- Avoid canceling contexts mid-flush (e.g. during shutdown); use a detached context for flushes.
- Surface the wrapped inner error, not just the wrapper message.
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
- error deleting file: %v
- error getting zone files: %v
- error getting file: %v
- flush already in progress
- error getting file: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/89b3d614a5f6bde3.
Report an issue: GitHub.