plandex-ai/plandex · error
failed to load context: %v
Error message
failed to load context: %v
What it means
AutoLoadContextFiles drains errCh once per input file and returns this wrapper on the first non-nil error received from any per-file goroutine. It is an aggregation point: the real cause (stat failure, read failure, or a per-file processing error) is the wrapped %v value.
Source
Thrown at app/cli/lib/context_auto_load.go:121
}
mu.Lock()
loadContextReqsByIndex[index] = &shared.LoadContextParams{
ContextType: contextType,
FilePath: path,
Name: path,
Body: body,
AutoLoaded: true,
ImageDetail: imageDetail,
}
mu.Unlock()
errCh <- nil
}(i, path)
}
for range files {
if e := <-errCh; e != nil {
return "", fmt.Errorf("failed to load context: %v", e)
}
}
// Convert map back to ordered slice
loadContextReqs := make(shared.LoadContextRequest, 0, len(loadContextReqsByIndex))
for i := 0; i < len(files); i++ {
if req := loadContextReqsByIndex[i]; req != nil {
loadContextReqs = append(loadContextReqs, req)
}
}
// even if there are no files to load, we still need to hit the API endpoint because the stream is waiting on a channel for the autoload to finish
res, apiErr := api.Client.AutoLoadContext(ctx, CurrentPlanId, CurrentBranch, loadContextReqs)
if apiErr != nil {
return "", fmt.Errorf("failed to load context: %v", apiErr.Msg)
}
if res.MaxTokensExceeded {View on GitHub (pinned to e2d772072e)
Solutions
- Unwrap the inner error to identify which file failed and why, then fix that specific path/permission.
- Validate all paths exist and are readable before calling AutoLoadContextFiles.
- Decide on policy: skip bad files with warnings (collect all errors, don't fail fast) for more robust loading.
- Reduce the file list to known-good files when running non-interactively.
- Inspect the errCh aggregation loop — because it returns on first error, remaining goroutines may still be running; ensure they are drained to avoid leaks.
Example fix
// before
for range files {
if e := <-errCh; e != nil {
return "", fmt.Errorf("failed to load context: %v", e)
}
}
// after
var errs []error
for range files {
if e := <-errCh; e != nil {
errs = append(errs, fmt.Errorf("%w", e))
}
}
if len(errs) > 0 {
log.Printf("skipped %d context files: %v", len(errs), errors.Join(errs...))
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate all inputs up front so goroutines never fail on obvious problems
for _, p := range files {
if p == "" {
return "", fmt.Errorf("empty path in file list")
}
if _, err := os.Stat(expandHome(p)); err != nil {
log.Printf("warning: %s unavailable: %v", p, err)
}
} Try / catch
var errs []error
for range files {
if e := <-errCh; e != nil {
errs = append(errs, e)
}
}
if len(errs) == len(files) {
return "", fmt.Errorf("failed to load context: %v", errors.Join(errs...))
}
if len(errs) > 0 {
log.Printf("partial load, skipped %d files: %v", len(errs), errors.Join(errs...))
} Prevention
- Unwrap the inner error to identify the exact failing file before debugging.
- Drain all goroutine errors instead of failing on the first, to avoid goroutine leaks and get full diagnostics.
- Validate every path (exists, readable, regular file) before dispatching goroutines.
- Decide an explicit skip-vs-fail policy for bad files based on how critical each context file is.
When it happens
Trigger: Any of the N goroutines sends a non-nil error on errCh — e.g. os.Stat/os.ReadFile failures, an unsupported context type for the file extension, or size accounting failing — and the collector loop hits it before all results are processed.
Common situations: Batch-loading a list of context files where at least one is missing, unreadable, or of an unsupported type; large file lists increase the odds one path is stale; concurrent goroutines racing on shared map/slice state during processing.
Related errors
- failed to get file info for %s: %v
- failed to read file %s: %v
- failed to read the file %s: %v
- failed to get file info for %s: %v
- error getting plan current branch: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/b1e0bd1cf23ca4ec.
Report an issue: GitHub.