plandex-ai/plandex · error

error applying plan: %v

Error message

error applying plan: %v

What it means

ApplyPlan aggregates errors from all its worker goroutines through errCh; the first non-nil value received during the numRoutines drain loop is wrapped as "error applying plan: %v". This is the outer wrapper for any inner failure — marshalling, file writes, storing descriptions, loading contexts, updating contexts, or a recovered panic — and it aborts the apply before the PlanApply record is persisted.

Source

Thrown at app/server/db/result_helpers.go:712

				)

				if err != nil {
					errCh <- fmt.Errorf("error updating context: %v", err)
					return
				}

				updateContextRes = res
			}
			errCh <- nil

		}()

	}

	for i := 0; i < numRoutines; i++ {
		err := <-errCh
		if err != nil {
			return fmt.Errorf("error applying plan: %v", err)
		}
	}

	// Store the PlanApply record
	planApply := &PlanApply{
		Id:        uuid.New().String(),
		OrgId:     orgId,
		PlanId:    planId,
		UserId:    userId,
		CommitMsg: params.CommitMsg,
		CreatedAt: now,
	}

	// Collect the IDs from the pending results and descriptions
	var resultIds []string
	var descriptionIds []string
	var messageIds []string

View on GitHub (pinned to e2d772072e)

Solutions

  1. Unwrap the message to see the inner error (e.g., "error loading context: ...", "error writing result file: ...", "panic in ApplyPlan: ...") and address that root cause.
  2. Check the results/applies directories exist and are writable (os.MkdirAll targets under the org data dir) and that disk space is available.
  3. Re-fetch the plan state and re-load contexts so file bodies and context IDs are current, then retry ApplyPlan.
  4. Ensure only one ApplyPlan runs per plan at a time to avoid races on shared maps and channels.
  5. If a panic is reported, fix the state mismatch it indicates (e.g., updated paths missing from contextsByPath) before retrying.

Example fix

// before: opaque outer error only
err := db.ApplyPlan(ctx, params) // error applying plan: <inner>

// after: log/inspect the wrapped cause before retry
err := db.ApplyPlan(ctx, params)
if err != nil {
    log.Printf("apply failed, inner cause: %s", err) // e.g. 'error loading context: ...'
    // fix root cause (refresh plan state / check storage), then retry
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: verify storage is writable and plan state is complete
if err := os.MkdirAll(resultsDir, 0755); err != nil {
    return fmt.Errorf("storage unavailable: %w", err)
}
if len(planState.CurrentPlanFiles.Files) == 0 {
    return fmt.Errorf("plan state has no files; nothing to apply")
}

Try / catch

err := db.ApplyPlan(ctx, params)
if err != nil {
    // err is 'error applying plan: <inner>'; unwrap the inner cause
    inner := strings.TrimPrefix(err.Error(), "error applying plan: ")
    log.Printf("ApplyPlan failed, cause: %s", inner)
    return fmt.Errorf("apply aborted, no PlanApply record written: %w", err)
}

Prevention

When it happens

Trigger: Any of the ApplyPlan goroutines sends a non-nil error on errCh: result file marshalling/writing failure, StoreDescription failure, LoadContexts failure (new files), UpdateContexts failure (updated files), or a recovered panic; the very first such error is what appears wrapped here.

Common situations: Disk full or unwritable results directory; malformed result objects failing JSON marshal; missing file bodies or stale context IDs from an out-of-date plan state; a nil-map panic in the update goroutine; storage permission changes on the org data directory.

Related errors


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