plandex-ai/plandex · critical
failed to rollback: %s
Error message
failed to rollback: %s
What it means
This is Rollback's aggregate top-level error. Rollback fans out goroutines that revert files, remove files, and prune new project paths, collecting their results from errCh. If any worker reported an error, Rollback returns 'failed to rollback: %s' with all collected errors, after still attempting every worker.
Source
Thrown at app/cli/lib/apply.go:814
for range toRemove {
err := <-pathsErrCh
if err != nil {
errCh <- fmt.Errorf("failed to remove %s: %s", toRemove, err.Error())
return
}
}
errCh <- nil
}()
errs := []error{}
for i := 0; i < numRoutines; i++ {
err := <-errCh
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return fmt.Errorf("failed to rollback: %s", errs)
}
if msg {
fmt.Println("🚫 Rolled back all changes")
}
return nil
}
View on GitHub (pinned to e2d772072e)
Solutions
- Read the appended child errors in the message — they identify which specific revert/remove operation failed.
- Fix the specific child error first (permissions, missing dirs, disk space).
- Check that no other process is modifying the project tree during rollback.
- Re-run Rollback after fixing; it is idempotent for paths that no longer exist if child errors are treated as non-fatal.
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before rollback
if _, err := os.Stat(fs.ProjectRoot); err != nil {
return err
}
// check writable tree
func writable(dir string) error { f, err := os.CreateTemp(dir, ".chk"); if err != nil { return err }; os.Remove(f.Name()); return nil } Try / catch
if err := Rollback(plan, true); err != nil {
var aggs []error
fmt.Fprintln(os.Stderr, "rollback failed:", err)
// parse child errors, fix root cause, re-run rollback
} Prevention
- Snapshot/backup the tree before applying so rollback is always possible.
- Run apply/rollback with the same user that owns the files.
- Quiesce other processes touching the project tree.
- Fix reported child errors before retrying — the aggregate lists them all.
When it happens
Trigger: Rollback() is called (directly or via handleApplyScript/execApplyScript) and at least one worker error was received on errCh — e.g. a revert write failed, a removal failed, or GetProjectPaths failed. The message is the aggregation of those child errors.
Common situations: Any of the underlying IO problems from errors 110-113; the rolled-back tree was concurrently modified; running without sufficient filesystem permissions; disk issues during a large rollback.
Related errors
- failed to get project paths: %v
- panic in operation: %v %s
- Error deleting org user: {err.Error()}
- connection to plan stream timed out due to missing heartbeat
- error loading accounts: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/acf685687adeaa9c.
Report an issue: GitHub.