plandex-ai/plandex · error
error writing file: %v
Error message
error writing file: %v
What it means
After the directory exists, the goroutine writes the original file body (context.Body) into the temp repo with os.WriteFile. A failure here (permissions, ENOSPC, invalid path, temp dir removed) is sent on errCh and later wrapped by GetPlanDiffs as 'error writing original files to temp dir: error writing file: ...'.
Source
Thrown at app/server/db/diff_helpers.go:72
log.Printf("panic in GetPlanDiffs: %v\n%s", r, debug.Stack())
errCh <- fmt.Errorf("panic in GetPlanDiffs: %v\n%s", r, debug.Stack())
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
_, hasPath := files[path]
_, hasRemoved := removed[path]
if hasPath || hasRemoved {
hasAnyOriginal = true
// ensure file directory exists
err = os.MkdirAll(filepath.Dir(filepath.Join(tempDirPath, path)), 0755)
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 {View on GitHub (pinned to e2d772072e)
Solutions
- Read the wrapped os error to identify ENOSPC/EACCES/ENAMETOOLONG and address that specific cause.
- Free disk space or increase quota for the org/tmp volume.
- Verify temp dir exists and is writable for the whole GetPlanDiffs run; stop concurrent cleanup jobs.
- Validate/sanitize the file path before writing (no NUL, no '..').
Example fix
// before
err = os.WriteFile(filepath.Join(tempDirPath, path), []byte(context.Body), 0644)
// after
if err := os.WriteFile(filepath.Join(tempDirPath, path), []byte(context.Body), 0644); err != nil {
errCh <- fmt.Errorf("error writing file %s: %v", path, err)
return
} Defensive patterns
Strategy: validation
Validate before calling
if len(context.Body) > maxFileBodyBytes {
return fmt.Errorf("file body for %s exceeds %d bytes", path, maxFileBodyBytes)
}
if err := hasFreeSpace(tempDirPath, uint64(len(context.Body))); err != nil {
return err
} Try / catch
out, err := GetPlanDiffs(orgId, planId, plain)
var pathErr *os.PathError
if err != nil && errors.As(err, &pathErr) {
log.Printf("filesystem failure on %s: %v", pathErr.Path, pathErr.Err)
// ENOSPC -> free space; EACCES -> fix permissions
} Prevention
- Alert on disk usage thresholds for the volume backing org/temp storage.
- Validate plan file paths and sizes before writing.
- Prevent concurrent cleanup of the temp dir while GetPlanDiffs runs.
- Run the server under a user with write access to the entire temp tree.
When it happens
Trigger: os.WriteFile(filepath.Join(tempDirPath, path), []byte(context.Body), 0644) fails: disk full, permissions, path too long, or temp dir deleted mid-run.
Common situations: Very large file bodies exceeding quota/disk; read-only mounts; tmp cleaner racing the goroutines; filenames from plan state that the local filesystem cannot represent.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- error writing convo message description: %v
- error writing result file: %v
- failed to read file %s: %v
- failed to open file %s: %w
- error creating account credentials directory: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/d1d7b4cfe2483947.
Report an issue: GitHub.