plandex-ai/plandex · error
error building race: %v
Error message
error building race: %v
What it means
buildStructuredEdits wraps any failure returned by fileState.buildRace (the fallback LLM race that fixes a failed auto-apply) into "error building race: %v" and forwards it via fileState.onBuildFileError. It is thrown when the race of fast-apply/model-based repair paths fails for a non-ApiError reason, meaning the file's edits could not be finalized. If the underlying error is a *shared.ApiError it is instead streamed to activePlan.StreamDoneCh and this message is not produced.
Source
Thrown at app/server/model/plan/build_structured_edits.go:171
proposedContent: proposedContent,
desc: desc,
reasons: autoApplyRes.NeedsVerifyReasons,
syntaxErrors: autoApplySyntaxErrors,
didCallFastApply: calledFastApply,
fastApplyCh: fastApplyCh,
sessionId: activePlan.SessionId,
}
buildRaceResult, err := fileState.buildRace(buildCtx, cancelBuild, buildRaceParams)
if err != nil {
if apiErr, ok := err.(*shared.ApiError); ok {
activePlan.StreamDoneCh <- apiErr
return
} else {
log.Printf("buildStructuredEdits - %s - error building race: %v\n", filePath, err)
fileState.onBuildFileError(fmt.Errorf("error building race: %v", err))
}
return
}
updated = buildRaceResult.content
}
// output diff and store build results
buildInfo := &shared.BuildInfo{
Path: filePath,
NumTokens: 0,
Finished: true,
}
log.Printf("streaming build info for finished file %s\n", filePath)
activePlan.Stream(shared.StreamMessage{
Type: shared.StreamMessageBuildInfo,
BuildInfo: buildInfo,
})View on GitHub (pinned to e2d772072e)
Solutions
- Check the wrapped inner error in the log line to identify the root cause (network, auth, or model output).
- Verify LLM provider credentials and rate limits; if it's a transient network failure, retry the plan build.
- If the underlying error is actually an API error, ensure it is typed as *shared.ApiError so it routes through StreamDoneCh instead of this path.
- Increase build context timeout or reduce file size so the repair race can complete.
Example fix
// before
buildRaceResult, err := fileState.buildRace(buildCtx, cancelBuild, buildRaceParams)
if err != nil {
log.Printf("error building race: %v", err)
}
// after
buildRaceResult, err := fileState.buildRace(buildCtx, cancelBuild, buildRaceParams)
if err != nil {
var apiErr *shared.ApiError
if errors.As(err, &apiErr) {
activePlan.StreamDoneCh <- apiErr
return
}
if errors.Is(err, context.Canceled) {
return // user canceled, don't report as failure
}
log.Printf("error building race: %v", err)
} Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check inputs before entering the race path
if updated == "" || proposedContent == "" {
return fmt.Errorf("cannot run build race with empty content")
} Type guard
var apiErr *shared.ApiError
if errors.As(err, &apiErr) {
// route to StreamDoneCh
activePlan.StreamDoneCh <- apiErr
return
}
if errors.Is(err, context.Canceled) {
return // not a real failure
} Try / catch
buildRaceResult, err := fileState.buildRace(buildCtx, cancelBuild, buildRaceParams)
if err != nil {
var apiErr *shared.ApiError
switch {
case errors.As(err, &apiErr):
activePlan.StreamDoneCh <- apiErr
case errors.Is(err, context.Canceled):
// swallow cancellation
default:
fileState.onBuildFileError(fmt.Errorf("error building race: %w", err))
}
return
} Prevention
- Use errors.As/errors.Is instead of a raw type assertion so wrapped ApiErrors are recognized.
- Handle context.Canceled explicitly so user cancellations aren't logged as build failures.
- Monitor LLM provider health and rate limits before launching repair races.
- Keep repair-race prompts and model configs validated in tests.
When it happens
Trigger: fileState.buildRace(buildCtx, cancelBuild, buildRaceParams) returns a non-nil error that is not *shared.ApiError — e.g. all racers in buildRace failed, LLM streaming call errored (network/timeout), or the repair candidates produced unusable output — while processing a file whose auto-apply had syntax errors or NeedsVerifyReasons.
Common situations: LLM provider outages or rate limits during the repair race, an invalid/expired auth token surfacing as a non-ApiError, malformed model responses that make every race branch fail, or context deadline exceeded on the build context.
Related errors
- error building whole file: %w
- fast apply validation failed: %w
- all build attempts failed: %v
- error getting diff replacements: %v
- error building validate: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/8409febac30f5c20.
Report an issue: GitHub.