plandex-ai/plandex · error
error writing original files to temp dir: %v
Error message
error writing original files to temp dir: %v
What it means
This is the aggregation point: the parent goroutine drains errCh once per entry in ContextsByPath, and any non-nil error sent by a worker (directory creation, file write, or recovered panic) is wrapped with this prefix and returned from GetPlanDiffs. It indicates one of the original-file versions could not be materialized in the temp git repo.
Source
Thrown at app/server/db/diff_helpers.go:83
if err != nil {
errCh <- fmt.Errorf("error creating directory: %v", err)
return
}
err = os.WriteFile(filepath.Join(tempDirPath, path), []byte(context.Body), 0644)
if err != nil {
errCh <- fmt.Errorf("error writing file: %v", err)
return
}
}
errCh <- nil
}(path, context)
}
for range planState.ContextsByPath {
err = <-errCh
if err != nil {
return "", fmt.Errorf("error writing original files to temp dir: %v", err)
}
}
if hasAnyOriginal {
// add and commit the files in the temp dir
err := gitAdd(tempDirPath, ".")
if err != nil {
return "", fmt.Errorf("error adding files to git repository for dir: %s, err: %v", tempDirPath, err)
}
err = gitCommit(tempDirPath, "original files")
if err != nil {
return "", fmt.Errorf("error committing files to git repository for dir: %s, err: %v", tempDirPath, err)
}
}
// write the current files to the temp dir
errCh = make(chan error, len(files))View on GitHub (pinned to e2d772072e)
Solutions
- Read the inner error after the prefix — it identifies the actual root cause (mkdir/write/panic) and the failing path.
- Fix that root cause per its own guidance (space, permissions, path sanitization, nil checks).
- Note the loop returns early without draining remaining workers; consider draining all errors to avoid leaked goroutine sends (buffered channel already prevents goroutine leaks).
- Add per-path context to the wrapped message for easier triage.
Example fix
// before
return "", fmt.Errorf("error writing original files to temp dir: %v", err)
// after
return "", fmt.Errorf("error writing original files to temp dir: %w", err) // use %w to allow errors.As/Is unwrapping Defensive patterns
Strategy: try-catch
Validate before calling
if len(planState.ContextsByPath) == 0 {
// nothing to diff from contexts; short-circuit or handle
} Try / catch
diffs, err := GetPlanDiffs(orgId, planId, plain)
if err != nil {
var inner error
if strings.Contains(err.Error(), "error writing original files to temp dir: ") {
inner = errors.New(strings.TrimPrefix(err.Error(), "error writing original files to temp dir: "))
log.Printf("inner cause: %v", inner)
}
return fmt.Errorf("plan diff unavailable: %w", err)
} Prevention
- Fix the underlying mkdir/write/panic error reported after the prefix — this error is only a wrapper.
- Use %w instead of %v when wrapping so callers can errors.Unwrap to the root cause.
- Consider reporting which path failed by including it in worker error messages.
- Keep the error channel buffered (it is) so a single failure cannot leak goroutines.
When it happens
Trigger: Any per-path goroutine for planState.ContextsByPath sends a non-nil error (from [362], [363], or [361]); the first error received aborts the whole diff computation.
Common situations: Same real-world causes as the inner errors: full disk, permission loss, deleted temp dir, panics on nil contexts; often seen on hosts with constrained /tmp or corrupted plan state.
Related errors
- error deleting pending results: %v
- failed to get file info for %s: %v
- failed to read file %s: %v
- failed to load context: %v
- failed to read the file %s: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/371375a91a865eca.
Report an issue: GitHub.