plandex-ai/plandex · error

error rejecting plan file: %v

Error message

error rejecting plan file: %v

What it means

Raised in buildFile when a reset operation for a file cannot be completed. For IsResetOp builds the code runs an ExecRepoOperation (write-locked git repo op) whose callback calls db.RejectPlanFile to reject pending changes for the file. Any failure from the repo operation or the rejection itself is wrapped as 'error rejecting plan file: %v' and sent to onBuildFileError, failing this file's build.

Source

Thrown at app/server/model/plan/build_exec.go:334

		err := db.ExecRepoOperation(db.ExecRepoOperationParams{
			OrgId:       currentOrgId,
			UserId:      fileState.currentUserId,
			PlanId:      planId,
			Branch:      branch,
			PlanBuildId: build.Id,
			Scope:       db.LockScopeWrite,
			Reason:      "reset file op",
			Ctx:         activePlan.Ctx,
			CancelFn:    activePlan.CancelFn,
		}, func(repo *db.GitRepo) error {
			now := time.Now()
			return db.RejectPlanFile(currentOrgId, planId, filePath, now)
		})

		if err != nil {
			log.Printf("Error rejecting plan file: %v\n", err)
			fileState.onBuildFileError(fmt.Errorf("error rejecting plan file: %v", err))
			return
		}

		buildInfo := &shared.BuildInfo{
			Path:      filePath,
			NumTokens: 0,
			Finished:  true,
			Removed:   fileState.contextPart == nil,
		}

		activePlan.Stream(shared.StreamMessage{
			Type:      shared.StreamMessageBuildInfo,
			BuildInfo: buildInfo,
		})

		time.Sleep(200 * time.Millisecond)

		fileState.onBuildProcessed(activeBuild)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped err in the log to see whether it came from the repo lock or from RejectPlanFile
  2. Retry the reset — transient repo-lock contention or cancellation is the most common cause
  3. Confirm the plan file has a pending record to reject; if already rejected, the file may just need a refresh instead of a reset
  4. Check DB connectivity/health if RejectPlanFile persistently fails
  5. Avoid triggering conflicting operations (edit + reset on the same file) simultaneously

Example fix

// before: two concurrent ops on same file cause lock contention
// resetOp + build on same path at once
// after: ensure ops are serialized — wait for the build to finish before issuing reset
if !activePlan.IsBuildingByPath[filePath] {
    err := db.ExecRepoOperation(params, func(repo *db.GitRepo) error {
        return db.RejectPlanFile(currentOrgId, planId, filePath, time.Now())
    })
}
Defensive patterns

Strategy: retry

Validate before calling

if activeBuild.IsResetOp && !activePlan.IsBuildingByPath[filePath] {
    // safe to issue the reset — no conflicting build in flight
}

Try / catch

err := db.ExecRepoOperation(params, func(repo *db.GitRepo) error {
    return db.RejectPlanFile(orgId, planId, filePath, time.Now())
})
if err != nil {
    if errors.Is(err, context.Canceled) {
        return // user canceled; do not surface as failure
    }
    // retry once on lock contention
}

Prevention

When it happens

Trigger: A reset-file build executes and either the write-locked ExecRepoOperation fails (repo lock contention/cancelation, git repo error) or db.RejectPlanFile fails to persist the rejection (DB write error, missing plan file record for the path).

Common situations: User clicks 'revert/reset changes' on a plan file whose pending record was already cleared or deleted; concurrent builds/edits hold the repo write lock; database outage or constraint violation during StoreDescription/RejectPlanFile; operation canceled via plan CancelFn mid-reset.

Related errors


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