{"record":{"id":"ea7aa8cb616d942b","repo":"plandex-ai/plandex","slug":"failed-to-write-s-w","errorCode":null,"errorMessage":"failed to write %s: %w","messagePattern":"failed to write (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/rewind.go","lineNumber":297,"sourceCode":"\t\t\t\t}\n\t\t\t\t// Mark parent directory for cleanup\n\t\t\t\tparentDir := filepath.Dir(dstPath)\n\t\t\t\tmu.Lock()\n\t\t\t\tdirsToCheck[parentDir] = true\n\t\t\t\tmu.Unlock()\n\t\t\t\terrCh <- nil\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Ensure directory exists\n\t\t\tif err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"failed to create directory for %s: %w\", path, err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Write the file\n\t\t\tif err := os.WriteFile(dstPath, []byte(content), 0644); err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"failed to write %s: %w\", path, err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\terrCh <- nil\n\t\t}(path, content)\n\t}\n\n\t// Collect any errors\n\tfor i := 0; i < len(requiredChanges); i++ {\n\t\tif err := <-errCh; err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Clean up empty directories\n\tfor dir := range dirsToCheck {\n\t\tif err := RemoveEmptyDirs(dir, fs.ProjectRoot); err != nil {\n\t\t\t// Log but don't fail the operation for directory cleanup errors","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/rewind.go#L279-L315","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif err := os.WriteFile(dstPath, []byte(content), 0644); err != nil { ... }\n// after\nif err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { ... }\nif info, err := os.Stat(dstPath); err == nil && info.IsDir() { os.RemoveAll(dstPath) }\nif err := os.WriteFile(dstPath, []byte(content), 0644); err != nil { ... }","handlingStrategy":"try-catch","validationCode":"// before calling rewind/restore\nif st, err := os.Stat(projectDir); err != nil || !st.IsDir() {\n    return fmt.Errorf(\"project dir not writable: %v\", err)\n}\nif unix.Access(projectDir, unix.W_OK) != nil {\n    return fmt.Errorf(\"no write permission on %s\", projectDir)\n}","typeGuard":"func isWritableDir(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.IsDir() && unix.Access(path, unix.W_OK) == nil\n}","tryCatchPattern":"err := <-errCh\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && perr.Err == syscall.ENOSPC {\n        // handle disk-full: free space and retry\n    }\n    return err\n}","preventionTips":["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"],"tags":["filesystem","io","write-permission"],"backgroundTag":"file-write-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}