plandex-ai/plandex · error
error writing convo message description: %v
Error message
error writing convo message description: %v
What it means
After marshaling, StoreDescription writes the JSON to descriptionsDir/<id>.json via os.WriteFile. This error wraps any OS-level failure of that write: permissions, missing directory, disk full, or I/O errors.
Source
Thrown at app/server/db/plan_helpers.go:346
now := time.Now()
if description.Id == "" {
description.Id = uuid.New().String()
description.CreatedAt = now
}
description.UpdatedAt = now
bytes, err := json.Marshal(description)
if err != nil {
return fmt.Errorf("error marshalling convo message description: %v", err)
}
err = os.WriteFile(filepath.Join(descriptionsDir, description.Id+".json"), bytes, os.ModePerm)
if err != nil {
return fmt.Errorf("error writing convo message description: %v", err)
}
return nil
}
func DeleteDraftPlans(orgId, projectId, userId string) error {
res, err := Conn.Query("DELETE FROM plans WHERE project_id = $1 AND owner_id = $2 AND name = 'draft' RETURNING id;", projectId, userId)
if err != nil {
return fmt.Errorf("error deleting draft plans: %v", err)
}
defer res.Close()
// get ids
var ids []string
for res.Next() {
var id stringView on GitHub (pinned to e2d772072e)
Solutions
- Check the wrapped OS error (ENOSPC, EACCES) and fix storage capacity/permissions
- Verify description.Id is non-empty before writing
- Ensure directory creation and write use consistent, non-racy lifecycle (don't delete plan dir concurrently)
- Use a safer permission mode (e.g. 0o644) instead of os.ModePerm on the file
- Mount the storage volume read-write and monitor disk usage
Example fix
// before
if description.Id == "" {
// proceeds and writes ".json"
}
err = os.WriteFile(filepath.Join(descriptionsDir, description.Id+".json"), bytes, os.ModePerm)
// after
if description.Id == "" {
return fmt.Errorf("cannot store description: empty id")
}
if err := os.WriteFile(filepath.Join(descriptionsDir, description.Id+".json"), bytes, 0o644); err != nil {
return fmt.Errorf("error writing convo message description: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
if description.Id == "" {
return fmt.Errorf("description id is empty")
}
if err := validateDirWritable(descriptionsDir); err != nil {
return err
} Try / catch
if err := StoreDescription(desc); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOSPC) {
// free disk space / alert ops
}
return err
} Prevention
- Reject empty plan/description ids before persistence
- Monitor disk usage and quotas on the storage volume
- Don't delete plan dirs concurrently with writes
- Use explicit file modes (0o644) rather than os.ModePerm
When it happens
Trigger: os.WriteFile(filepath.Join(descriptionsDir, description.Id+".json"), bytes, os.ModePerm) fails: directory was removed between MkdirAll and the write, permission denied, ENOSPC (disk full), description.Id is empty producing ".json", or read-only filesystem.
Common situations: Disk quota exceeded on the storage volume; concurrent DeletePlanDir removing the plan directory while a description write is in flight; empty Id due to upstream data bug; container filesystem mounted read-only after crash recovery.
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 result file: %v
- error writing current plan settings: %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/abac5ab4a1559ece.
Report an issue: GitHub.