plandex-ai/plandex · error
error reading result file: %v
Error message
error reading result file: %v
What it means
The per-file goroutine in GetPlanFileResults calls os.ReadFile on the result file; any read failure (permissions, file vanished between listing and reading, I/O error) is reported on errCh as this wrapped error including the underlying os error.
Source
Thrown at app/server/db/result_helpers.go:411
errCh := make(chan error, len(files))
resultCh := make(chan *PlanFileResult, len(files))
for _, file := range files {
// log.Printf("Result file: %s", file.Name())
go func(file os.DirEntry) {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in GetPlanFileResults: %v\n%s", r, debug.Stack())
errCh <- fmt.Errorf("panic in GetPlanFileResults: %v\n%s", r, debug.Stack())
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
bytes, err := os.ReadFile(filepath.Join(resultsDir, file.Name()))
if err != nil {
errCh <- fmt.Errorf("error reading result file: %v", err)
return
}
var result PlanFileResult
err = json.Unmarshal(bytes, &result)
if err != nil {
errCh <- fmt.Errorf("error unmarshalling result file: %v", err)
return
}
resultCh <- &result
}(file)
}
for i := 0; i < len(files); i++ {
select {
case err := <-errCh:View on GitHub (pinned to e2d772072e)
Solutions
- Verify no concurrent job deletes files from the results directory during listing
- Check file permissions and ownership of the result JSON files
- Re-run the call; a race with cleanup is often transient
- Hardening: skip files that disappear mid-read instead of failing the whole call
Example fix
// before
if err != nil {
errCh <- fmt.Errorf("error reading result file: %v", err)
return
}
// after: tolerate files removed concurrently
if err != nil {
if os.IsNotExist(err) {
return // file was deleted during listing
}
errCh <- fmt.Errorf("error reading result file: %v", err)
return
} Defensive patterns
Strategy: retry
Validate before calling
fi, err := os.Stat(filepath.Join(dir, name))
if err != nil { log.Printf("result file missing/unreadable: %s", name) } Try / catch
results, err := db.GetPlanFileResults(orgId, planId)
if err != nil && strings.Contains(err.Error(), "error reading result file") {
time.Sleep(100 * time.Millisecond)
results, err = db.GetPlanFileResults(orgId, planId) // transient deletion race
} Prevention
- Avoid deleting result files while readers are active
- Use atomic rename when cleaning up results
- Check for symlink/permission issues on the results dir
When it happens
Trigger: File deleted or renamed by another process after ReadDir listed it; permission denied on the file; symlink pointing to a missing target.
Common situations: Concurrent cleanup of result files while GetPlanFileResults iterates; results synced/rotated externally; read-only or stale NFS mounts.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to read the file %s: %v
- error getting plan current branch: %v
- error reading settings-v2.json: %v
- failed to seek in temporary file: %w
- error reading convo dir: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/674149f867be0523.
Report an issue: GitHub.