gastownhall/beads · error
failed to close temp file: %w
Error message
failed to close temp file: %w
What it means
atomicWriteFile explicitly closes the temp file after syncing; this wraps a tmp.Close failure. A failed close means buffered data may not have reached disk reliably, so the temp file is discarded and the destination untouched.
Source
Thrown at cmd/bd/backup_export.go:116
tmp, err := os.CreateTemp(dir, ".backup-tmp-*")
if err != nil {
return fmt.Errorf("failed to create temp file: %w", err)
}
tmpPath := tmp.Name()
if _, err := tmp.Write(data); err != nil {
_ = tmp.Close()
_ = os.Remove(tmpPath)
return fmt.Errorf("failed to write temp file: %w", err)
}
if err := tmp.Sync(); err != nil {
_ = tmp.Close()
_ = os.Remove(tmpPath)
return fmt.Errorf("failed to sync temp file: %w", err)
}
if err := tmp.Close(); err != nil {
_ = os.Remove(tmpPath)
return fmt.Errorf("failed to close temp file: %w", err)
}
if err := os.Rename(tmpPath, path); err != nil {
_ = os.Remove(tmpPath)
return fmt.Errorf("failed to rename temp file: %w", err)
}
return nil
}
// runBackupExport performs a Dolt-native backup to .beads/backup/.
// Returns the updated state.
func runBackupExport(ctx context.Context, force bool) (*backupState, error) {
dir, err := backupDir()
if err != nil {
return nil, err
}
state, err := loadBackupState(dir)
if err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Check open file descriptor limits and usage: ulimit -n; lsof | wc -l.
- Raise the limit if exhausted (ulimit -n 4096 or systemd LimitNOFILE) or fix leaking processes.
- Retry the command — atomic write guarantees the previous backup_state.json is intact.
- If persistent, check for system-wide file table exhaustion (fs.file-max).
Example fix
// shell ulimit -n 4096 && bd sync
Defensive patterns
Strategy: validation
Validate before calling
// fd exhaustion is the usual cause; check headroom before running
count, _ := filepath.Glob("/proc/self/fd/*")
if len(count) > 900 { // typical soft limit 1024
return errors.New("too many open fds before bd operation")
} Try / catch
if err := saveBackupState(dir, state); err != nil {
if strings.Contains(err.Error(), "close temp file") {
log.Printf("fd pressure suspected; raise ulimit -n and retry: %v", err)
return err
}
return err
} Prevention
- Raise NOFILE limits in CI/systemd (LimitNOFILE=4096)
- Fix descriptor leaks in long-running wrapper processes
- Avoid nesting many bd invocations concurrently in one shell environment
When it happens
Trigger: tmp.Close() returns non-nil: file descriptor exhaustion (EMFILE), or a deferred write error surfaced at close.
Common situations: Process hit its open-file limit (ulimit -n) due to leaked descriptors; kernel memory pressure preventing flush.
Related errors
- failed to create temp file: %w
- failed to rename temp file: %w
- ensureProxiedServerConfig: write %s: %w
- identity: write proxy secret: %w
- dolt path is not executable
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/abd04caf73d86afc.
Report an issue: GitHub.