plandex-ai/plandex · error

active plan not found for plan ID %s and branch %s

Error message

active plan not found for plan ID %s and branch %s

What it means

During build validate-and-fix retry handling, the active plan lookup by plan ID + branch returns no plan, so validation retries cannot proceed. Means the plan was deleted/concurrently changed while a build was in flight.

Source

Thrown at app/server/model/plan/build_validate_and_fix.go:468

	// log.Printf("Final content:\n\n%s", final)

	return buildValidateResult{valid: false, updated: final, problem: problem}, nil
}

func (fileState *activeBuildStreamFileState) validationRetryOrError(buildCtx context.Context, validateParams buildValidateParams, err error) (buildValidateResult, error) {
	log.Printf("Handling validation error for file: %s", fileState.filePath)
	if fileState.validationNumRetry < MaxBuildErrorRetries {
		fileState.validationNumRetry++

		log.Printf("Retrying validation (attempt %d/%d) due to error: %v",
			fileState.validationNumRetry, MaxBuildErrorRetries, err)

		activePlan := GetActivePlan(fileState.plan.Id, fileState.branch)

		if activePlan == nil {
			log.Printf("Active plan not found for plan ID %s and branch %s",
				fileState.plan.Id, fileState.branch)
			return buildValidateResult{}, fmt.Errorf("active plan not found for plan ID %s and branch %s",
				fileState.plan.Id, fileState.branch)
		}

		select {
		case <-buildCtx.Done():
			log.Printf("Context canceled during retry wait")
			return buildValidateResult{}, context.Canceled
		case <-time.After(time.Duration(fileState.validationNumRetry*fileState.validationNumRetry)*200*time.Millisecond + time.Duration(rand.Intn(500))*time.Millisecond):
			log.Printf("Retry wait completed, attempting validation again")
			break
		}

		return fileState.buildValidate(buildCtx, validateParams)
	} else {
		log.Printf("Max retries (%d) exceeded, returning error", MaxBuildErrorRetries)
		return buildValidateResult{}, err
	}
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Ensure the plan is created and activated before starting build validation
  2. Verify fileState.plan.Id and fileState.branch match a registered active plan
  3. Check for code that deactivates/removes plans concurrently with the build
Defensive patterns

Strategy: try-catch

Validate before calling

if GetActivePlan(planId, branch) == nil {
    return fmt.Errorf("plan %s not active on branch %s; activate before building", planId, branch)
}

Type guard

func planIsActive(planId, branch string) bool { return GetActivePlan(planId, branch) != nil }

Try / catch

res, err := buildValidate(ctx, ...)
if err != nil && strings.Contains(err.Error(), "active plan not found") {
    // re-activate or re-create the plan, then retry once
}

Prevention

When it happens

Trigger: buildValidate reaches the retry/error path while the plan identified by fileState.plan.Id and fileState.branch is no longer active (removed or never registered).

Common situations: Plan was deleted/finished concurrently, wrong branch name, or the plan was never activated before the build ran.

Related errors


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