plandex-ai/plandex · error

error building whole file: %w

Error message

error building whole file: %w

What it means

In buildRace (app/server/model/plan/build_race.go), the whole-file fallback build goroutine called buildWholeFileFallback and got a non-nil, non-cancellation error. This wrapper wraps the underlying error with %w so the root cause is preserved via errors.Is/Unwrap. It means the model-based full-file rewrite fallback could not produce content, not a syntax or validation problem.

Source

Thrown at app/server/model/plan/build_race.go:106

				}
			}()
			select {
			case <-buildCtx.Done():
				log.Printf("buildRace - context already canceled, skipping whole file build")
				return
			default:
			}

			content, err := fileState.buildWholeFileFallback(buildCtx, proposedContent, desc, comments, sessionId)

			if err != nil {
				if errors.Is(err, context.Canceled) {
					log.Printf("Context canceled during whole file build")
					return
				}

				log.Printf("buildRace - whole file build failed: %v", err)
				sendErr(fmt.Errorf("error building whole file: %w", err))
			} else {
				log.Printf("buildRace - whole file build succeeded")
				sendRes(raceResult{content: content, valid: true})
			}
		}()
	}

	maybeStartFastApply := func(onFail func()) {
		log.Printf("buildRace - starting fast apply")
		if !params.didCallFastApply {
			log.Printf("buildRace - fast apply isn't defined, skipping")
			sendErr(nil) // no error, just no fast apply
			onFail()
			return
		}

		go func() {
			defer func() {

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped cause with errors.Is/errors.As or read the log line 'buildRace - whole file build failed' immediately preceding it
  2. Check LLM provider connectivity/API keys/rate limits used by buildWholeFileFallback
  3. Verify the error type matches context.Canceled correctly (errors.Is, not ==) so cancellations are not misreported
  4. Retry the whole plan/build operation once the transient provider issue clears

Example fix

// before
sendErr(fmt.Errorf("error building whole file: %w", err))
// after
if errors.Is(err, context.DeadlineExceeded) || isTransient(err) {
	log.Printf("retrying whole file build after transient error: %v", err)
	content, err = fileState.buildWholeFileFallback(buildCtx, proposedContent, desc, comments, sessionId)
}
if err != nil {
	sendErr(fmt.Errorf("error building whole file: %w", err))
	return
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go has no pre-call validation; guard the inputs
if proposedContent == "" || sessionId == "" {
	return fmt.Errorf("cannot start whole file build: missing proposedContent or sessionId")
}
if err := buildCtx.Err(); err != nil {
	return err // skip build if already canceled
}

Type guard

func isCancellation(err error) bool {
	return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

content, err := fileState.buildWholeFileFallback(buildCtx, proposedContent, desc, comments, sessionId)
if err != nil {
	if isCancellation(err) {
		return // user cancel: not a real failure
	}
	sendErr(fmt.Errorf("error building whole file: %w", err))
	return
}

Prevention

When it happens

Trigger: The <PlandexIncorrect/> marker was detected (or the initial replacement loop failed), triggering startWholeFileBuild; buildWholeFileFallback then returned an error (e.g. the LLM sub-request failed, streaming error, or internal error) that is not context.Canceled.

Common situations: LLM provider outages or rate limits during the fallback rewrite; context deadline errors other than context.Canceled (e.g. custom wrappers that don't match context.Canceled); nil session/config in the fallback path; network drops mid-stream.

Related errors


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