plandex-ai/plandex · error
%v (from err.Error())
Error message
%v (from err.Error())
What it means
onBuildFileError is the generic per-file build error handler: whenever a file build (execPlanBuild, buildFile, buildStructuredEdits, buildWholeFileFallback) fails for any reason, the raw err.Error() text is sent to the client as a 500 ApiError via StreamDoneCh and recorded on build.Error via db.SetBuildError. The message shown is the underlying error, so its content varies — LLM stream failures, parse failures, context cancellation, etc.
Source
Thrown at app/server/model/plan/build_finish.go:301
activePlan := GetActivePlan(planId, branch)
if activePlan == nil {
log.Println("onBuildFileError - Active plan not found")
return
}
log.Printf("Error for file %s: %v\n", filePath, err)
activeBuild.Success = false
activeBuild.Error = err
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error for file %s: %v", filePath, err))
activePlan.StreamDoneCh <- &shared.ApiError{
Type: shared.ApiErrorTypeOther,
Status: http.StatusInternalServerError,
Msg: err.Error(),
}
if err != nil {
log.Printf("Error storing plan error result: %v\n", err)
}
build.Error = err.Error()
err = db.SetBuildError(build)
if err != nil {
log.Printf("Error setting build error: %v\n", err)
}
}
func (fileState *activeBuildStreamFileState) buildNextInQueue() bool {
filePath := fileState.filePath
activePlan := GetActivePlan(fileState.plan.Id, fileState.branch)
if activePlan == nil {
log.Println("onFinishBuildFile - Active plan not found")View on GitHub (pinned to e2d772072e)
Solutions
- Read the actual Msg sent to the client (it's err.Error()) and the server log line "Error for file <path>: ..." to identify the underlying failure
- If it's a provider/stream error, check API keys, rate limits, and provider status, then retry the build
- If the response failed to parse/apply, retry the operation or switch to a stronger model / whole-file fallback
- If context length is implicated, add fewer files to context or reduce the target file size
- The build's Error field is persisted via db.SetBuildError — inspect the build record for the retained message
Defensive patterns
Strategy: try-catch
Try / catch
// the client receives the 500 ApiError on the stream; handle and inspect Msg
resp, err := client.GetPlanBuildStream(...)
if apiErr, ok := err.(*shared.ApiError); ok {
log.Printf("build failed for plan: %s (type=%s status=%d)", apiErr.Msg, apiErr.Type, apiErr.Status)
if strings.Contains(apiErr.Msg, "context length") {
// trim plan context and retry
} else if isProviderError(apiErr.Msg) {
// check keys/rate limits and retry
}
} Prevention
- Keep LLM API keys valid and monitor provider rate limits/status before large builds
- Keep target files and plan context within the configured model's context window
- Retry failed builds — many underlying causes (provider blips, truncation) are transient
- Inspect the persisted build.Error field (SetBuildError) when triaging failures after the fact
When it happens
Trigger: Any failure inside a file build path that calls onBuildFileError: the model stream errored or was canceled, the LLM response failed validation/parsing into file edits, context length exceeded, or an internal step returned an error that bubbles to this handler.
Common situations: LLM provider outages or rate limits during a build; malformed model output that can't be applied as edits; plan canceled while a file was streaming; context window too small for the target file; misconfigured API keys causing provider errors.
Related errors
- Error storing plan result: planRes is nil
- error committing plan build: %v
- Error storing plan build result: %v
- error getting plan modelContext: %v
- error getting pending builds by path: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/5d7a7a0fe927cb3e.
Report an issue: GitHub.