plandex-ai/plandex · error
failed to write %s: %w
Error message
failed to write %s: %w
What it means
This error wraps the failure of os.WriteFile while a rewind/restore operation materializes files from stored content in a goroutine. It means the directory was created successfully but writing the file bytes to dstPath failed. The underlying os error (permissions, disk full, path issues) is included via %w.
Source
Thrown at app/cli/lib/rewind.go:297
}
// Mark parent directory for cleanup
parentDir := filepath.Dir(dstPath)
mu.Lock()
dirsToCheck[parentDir] = true
mu.Unlock()
errCh <- nil
return
}
// Ensure directory exists
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
errCh <- fmt.Errorf("failed to create directory for %s: %w", path, err)
return
}
// Write the file
if err := os.WriteFile(dstPath, []byte(content), 0644); err != nil {
errCh <- fmt.Errorf("failed to write %s: %w", path, err)
return
}
errCh <- nil
}(path, content)
}
// Collect any errors
for i := 0; i < len(requiredChanges); i++ {
if err := <-errCh; err != nil {
return err
}
}
// Clean up empty directories
for dir := range dirsToCheck {
if err := RemoveEmptyDirs(dir, fs.ProjectRoot); err != nil {
// Log but don't fail the operation for directory cleanup errorsView on GitHub (pinned to e2d772072e)
Solutions
- Check disk space (df -h) and free space if full
- Verify write permissions on the destination directory and file (chmod/chown)
- Check whether dstPath exists as a directory and remove/rename it
- Re-run the rewind from a writable checkout
Example fix
// before
if err := os.WriteFile(dstPath, []byte(content), 0644); err != nil { ... }
// after
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { ... }
if info, err := os.Stat(dstPath); err == nil && info.IsDir() { os.RemoveAll(dstPath) }
if err := os.WriteFile(dstPath, []byte(content), 0644); err != nil { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// before calling rewind/restore
if st, err := os.Stat(projectDir); err != nil || !st.IsDir() {
return fmt.Errorf("project dir not writable: %v", err)
}
if unix.Access(projectDir, unix.W_OK) != nil {
return fmt.Errorf("no write permission on %s", projectDir)
} Type guard
func isWritableDir(path string) bool {
info, err := os.Stat(path)
return err == nil && info.IsDir() && unix.Access(path, unix.W_OK) == nil
} Try / catch
err := <-errCh
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) && perr.Err == syscall.ENOSPC {
// handle disk-full: free space and retry
}
return err
} Prevention
- Check free disk space before large restores
- Ensure no path in the snapshot collides with an existing directory name
- Run the CLI as a user with write access to the project tree
- Avoid restoring onto read-only mounts
When it happens
Trigger: os.WriteFile(dstPath, content, 0644) fails during a rewind restore: read-only filesystem, insufficient permissions, disk quota exceeded, dstPath is actually a directory, or path exceeds filesystem limits.
Common situations: Restoring a checkpoint into a directory where a subpath exists as a directory with the target file's name; project on a mounted read-only volume; out of disk space; file locked/owned by another user after switching environments.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- failed to read file %s: %v
- failed to open file %s: %w
- error creating account credentials directory: %v
- error writing account credentials: %v
- error checking model settings file: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/ea7aa8cb616d942b.
Report an issue: GitHub.