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

  1. Read the wrapped cause to see which sub-step of RejectPlanFile failed
  2. Re-run RejectAllResults — transient/concurrent cases often succeed on retry
  3. Validate/repair the specific <resultId>.json content (truncated/corrupt files may need removal)
  4. 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

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/cb896f1edaac5e1b. Report an issue: GitHub.