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

  1. Read the inner error after the prefix — it identifies the actual root cause (mkdir/write/panic) and the failing path.
  2. Fix that root cause per its own guidance (space, permissions, path sanitization, nil checks).
  3. Note the loop returns early without draining remaining workers; consider draining all errors to avoid leaked goroutine sends (buffered channel already prevents goroutine leaks).
  4. 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

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


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