charmbracelet/crush · error
failed to write provider data to cache: %w
Error message
failed to write provider data to cache: %w
What it means
Thrown by cache.Store() when the atomic write (temp file + rename via atomicWriteFile) fails to persist the marshaled provider data. The atomic design protects concurrent Crush instances from reading a half-written cache, but the final write/rename can still fail at the OS level.
Source
Thrown at internal/config/provider.go:300
}
func (c cache[T]) Store(v T) error {
slog.Info("Saving provider data to disk", "path", c.path)
if err := os.MkdirAll(filepath.Dir(c.path), 0o755); err != nil {
return fmt.Errorf("failed to create directory for provider cache: %w", err)
}
data, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("failed to marshal provider data: %w", err)
}
// Written through a temporary file and renamed into place. Several Crush
// instances start independently and race to refresh this cache, and a
// truncating write would let one of them read a half-written catalog and
// silently fall back to the bundled copy.
if err := atomicWriteFile(c.path, data, 0o644); err != nil {
return fmt.Errorf("failed to write provider data to cache: %w", err)
}
return nil
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Free disk space / check quota (df -h) on the cache volume.
- Fix permissions on the cache directory and existing cache file.
- Ensure the path and its temp file are on the same filesystem so rename succeeds.
- Check for mandatory access control denials (audit logs) and adjust policy.
- Retry the update once the filesystem issue is resolved; the previous cache remains intact.
Example fix
// before Store(providers) // ENOSPC // after df -h ~/.cache/crush # free space, then retry crush update-providers
Defensive patterns
Strategy: retry
Validate before calling
dir := filepath.Dir(cachePath)
if err := unix.Access(dir, unix.W_OK); err != nil { /* warn: unwritable */ }
// also check free space periodically Try / catch
err := cache.Store(v)
for i := 0; err != nil && i < 3; i++ {
time.Sleep(100 * time.Millisecond)
err = cache.Store(v)
} Prevention
- Monitor disk space/quota on the cache volume
- Keep cache dir writable and on the same filesystem as its temp files
- Don't remount read-only while Crush runs
- Old cache survives failed writes — retry safely
When it happens
Trigger: atomicWriteFile(c.path, data, 0o644) fails: disk full (ENOSPC), permission denied on the target directory or existing file, the temp file cannot be created/renamed (cross-device), or the filesystem is read-only.
Common situations: Quota exceeded on the cache volume; read-only filesystem after mount remount; concurrent writers on a filesystem where rename semantics differ; SELinux/AppArmor denial.
Related errors
- failed to create server working directory: %v
- failed to save providers to cache: %w
- failed to save Hyper provider to cache: %w
- failed to read provider cache file: %w
- failed to create directory for provider cache: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/ea766773301ba973.
Report an issue: GitHub.