plandex-ai/plandex · warning
validation loop failed: %s
Error message
validation loop failed: %s
What it means
This error is raised when buildValidateLoop completes without error but reports the proposed content as invalid (validateResult.valid == false). The loop's human-readable reason for rejection (validateResult.problem) is included so the caller knows why the auto-apply edits did not validate.
Source
Thrown at app/server/model/plan/build_race.go:266
fileState.builderRun.AutoApplyValidationFinishedAt = time.Now()
if err != nil {
if errors.Is(err, context.Canceled) {
log.Printf("Context canceled during buildValidate")
return
}
log.Printf("buildRace - validation loop failed: %v", err)
sendErr(fmt.Errorf("error building validate loop: %w", err))
} else {
log.Printf("buildRace - validation loop finished, valid: %v", validateResult.valid)
if validateResult.valid {
log.Printf("buildRace - validation loop succeeded, valid: %v", validateResult.valid)
sendRes(raceResult{content: validateResult.updated, valid: validateResult.valid})
} else {
log.Printf("buildRace - validation loop failed, valid: %v", validateResult.valid)
sendErr(fmt.Errorf("validation loop failed: %s", validateResult.problem))
}
}
}()
errs := []error{}
errChNumReceived := 0
for {
select {
case <-buildCtx.Done():
log.Printf("buildRace - context canceled")
return raceResult{}, buildCtx.Err()
case err := <-errCh:
errChNumReceived++
log.Printf("buildRace - error channel received %d: %v\n", errChNumReceived, err)
if err != nil {
errs = append(errs, err)View on GitHub (pinned to e2d772072e)
Solutions
- Read validateResult.problem in the error text to see the specific rejection reason
- Retry the build so the model regenerates edits (this is a content problem, not infrastructure)
- Fall back to a whole-file build (buildRace already starts fallbacks, but a manual re-run with more context helps)
- Provide clearer desc/reasons context so the model produces applicable edits
Example fix
// before
res, err := fileState.buildRace(...)
applyEdits(res.content)
// after
res, err := fileState.buildRace(...)
if err != nil && strings.Contains(err.Error(), "validation loop failed") {
log.Printf("proposed edits invalid, regenerating: %v", err)
res, err = fileState.buildRace(...) // regenerate
}
applyEdits(res.content) Defensive patterns
Strategy: fallback
Validate before calling
if validateResult == nil {
return fmt.Errorf("no validation result produced")
}
if !validateResult.valid && validateResult.problem == "" {
return fmt.Errorf("validation rejected edits without a reason")
} Type guard
func isValidatedResult(r *buildValidateLoopResult) bool {
return r != nil && r.valid && r.updated != ""
} Try / catch
res, err := fileState.buildRace(...)
if err != nil {
if strings.Contains(err.Error(), "validation loop failed:") {
log.Printf("edits rejected: %s — falling back to whole-file build", err)
return startWholeFileBuild("")
}
return err
} Prevention
- Check the problem text in the error to fix the specific edit-generation issue
- Fall back to a whole-file build when replacements repeatedly fail validation
- Ensure edit markers strictly match current file content before applying
- Regenerate rather than applying known-invalid proposed content
When it happens
Trigger: buildValidateLoop finishes successfully but its validation step rejects the proposed edits — validateResult.valid is false with a populated validateResult.problem (e.g. edits don't apply cleanly, syntax errors remain, or the LLM validator deems the result wrong).
Common situations: Model output produced edits that conflict with the current file, replacement markers didn't match, or residual syntax errors after applying the proposed changes during auto-apply.
Related errors
- fast apply validation failed: %w
- error building validate loop: %w
- invalid context index: %s
- no context found with name: %s
- invalid value: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/52a6efc26f90caaf.
Report an issue: GitHub.