plandex-ai/plandex · error
error rejecting result: %v
Error message
error rejecting result: %v
What it means
Each goroutine in RejectAllResults calls RejectPlanFile(orgId, planId, resultId, now) to reject one pending result. If that call returns an error, it is wrapped with this message and sent to errCh. It means a single result file failed to be rejected; the parent surfaces it as 'error rejecting plan'.
Source
Thrown at app/server/db/result_helpers.go:820
errCh := make(chan error, len(files))
now := time.Now()
for _, file := range files {
resultId := strings.TrimSuffix(file.Name(), ".json")
go func(resultId string) {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in RejectAllResults: %v\n%s", r, debug.Stack())
errCh <- fmt.Errorf("panic in RejectAllResults: %v\n%s", r, debug.Stack())
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
err := RejectPlanFile(orgId, planId, resultId, now)
if err != nil {
errCh <- fmt.Errorf("error rejecting result: %v", err)
return
}
errCh <- nil
}(resultId)
}
for i := 0; i < len(files); i++ {
err := <-errCh
if err != nil {
return fmt.Errorf("error rejecting plan: %v", err)
}
}
return nil
}
func DeletePendingResultsForPaths(orgId, planId string, paths map[string]bool) error {View on GitHub (pinned to e2d772072e)
Solutions
- Read the wrapped cause to see which sub-step of RejectPlanFile failed
- Re-run RejectAllResults — transient/concurrent cases often succeed on retry
- Validate/repair the specific <resultId>.json content (truncated/corrupt files may need removal)
- Ensure only one process mutates the plan's results directory at a time (locking or leader election)
Example fix
// before
err := RejectPlanFile(orgId, planId, resultId, now)
if err != nil {
errCh <- fmt.Errorf("error rejecting result: %v", err)
return
}
// after: tolerate already-deleted files
err := RejectPlanFile(orgId, planId, resultId, now)
if err != nil {
if os.IsNotExist(err) {
errCh <- nil
return
}
errCh <- fmt.Errorf("error rejecting result %s: %v", resultId, err)
return
} Defensive patterns
Strategy: retry
Validate before calling
resultPath := filepath.Join(resultsDir, resultId+".json")
if _, err := os.Stat(resultPath); os.IsNotExist(err) {
return nil // already gone; nothing to reject
} Try / catch
err := RejectPlanFile(orgId, planId, resultId, now)
if err != nil {
if os.IsNotExist(err) {
errCh <- nil
return
}
errCh <- fmt.Errorf("error rejecting result %s: %v", resultId, err)
return
} Prevention
- Serialize reject/apply jobs per plan to avoid concurrent mutation
- Treat ENOENT as success in idempotent cleanup flows
- Log resultId with every failure for targeted follow-up
- Validate result file contents before processing and quarantine corrupt files
When it happens
Trigger: RejectPlanFile fails for one resultId — the result file disappeared between ReadDir and read, JSON unmarshal fails on corrupt content, a write/rename inside RejectPlanFile hits permissions or disk-full, or a sub-call rejects invalid state.
Common situations: Result file deleted concurrently by another cleanup job; truncated JSON from an earlier crashed write; read-only mount; two instances of the app processing the same plan simultaneously.
Related errors
- failed to read the file %s: %v
- error getting plan current branch: %v
- error reading convo files: %v
- error deleting draft plan dir: %v
- panic in DeleteOwnerPlans: %v %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/cb896f1edaac5e1b.
Report an issue: GitHub.