plandex-ai/plandex · error
error writing current plan: %v
Error message
error writing current plan: %v
What it means
The final step of WriteCurrentPlan persists the updated current-plan map to ~/.plandex/current-plans-v2.json with 0644 permissions. If os.WriteFile fails, the new current plan id is not recorded (CurrentPlanId is not updated) and this error wraps the OS-level reason.
Source
Thrown at app/cli/lib/plans.go:52
if currentPlanSettingsByAccount == nil {
currentPlanSettingsByAccount = &types.CurrentPlanSettingsByAccount{}
}
settings := types.CurrentPlanSettings{
Id: id,
}
(*currentPlanSettingsByAccount)[auth.Current.UserId] = &settings
bytes, err = json.Marshal(currentPlanSettingsByAccount)
if err != nil {
return fmt.Errorf("error marshalling current plan: %v", err)
}
err = os.WriteFile(HomeCurrentPlanPath, bytes, 0644)
if err != nil {
return fmt.Errorf("error writing current plan: %v", err)
}
CurrentPlanId = id
return nil
}
func ClearCurrentPlan() error {
if fs.HomePlandexDir == "" {
return fmt.Errorf("HomePlandexDir not set")
}
if CurrentProjectId == "" || HomeCurrentPlanPath == "" {
return fmt.Errorf("no current project")
}
var currentPlanSettingsByAccount *types.CurrentPlanSettingsByAccount
View on GitHub (pinned to e2d772072e)
Solutions
- Check free space: df -h ~ and clean up if the disk is full.
- Check ownership/permissions of ~/.plandex and the file: ls -ld ~/.plandex ~/.plandex/current-plans-v2.json; chown/chmod as needed.
- If the path is a directory or bad symlink, remove it so WriteFile can create the file.
- Re-run the command after fixing the filesystem; the write is idempotent.
Example fix
// before: no space left on device plandex new // error writing current plan: open ...: no space left on device // after: free space and retry df -h ~ # confirm space recovered plandex new
Defensive patterns
Strategy: validation
Validate before calling
home := os.Getenv("HOME")
if free, err := diskFree(home); err == nil && free < 1<<20 {
return fmt.Errorf("less than 1MB free in %s; plandex write will fail", home)
}
if fi, err := os.Stat(filepath.Join(home, ".plandex")); err != nil || !fi.IsDir() {
return fmt.Errorf("~/.plandex missing or not a directory")
} Type guard
func canWriteHomeState() bool {
f, err := os.OpenFile(filepath.Join(os.Getenv("HOME"), ".plandex", ".probe"), os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { return false }
f.Close(); os.Remove(f.Name())
return true
} Try / catch
if err := lib.WriteCurrentPlan(id); err != nil {
if strings.Contains(err.Error(), "error writing current plan") {
// check ENOSPC/EACCES in the wrapped message and remediate before retrying
}
} Prevention
- Monitor free disk space on the home partition.
- Run all plandex commands as the same (non-root) user.
- Keep ~/.plandex out of read-only mounts and restricted sandboxes.
- After any failure, verify the state file before retrying to avoid duplicate state.
When it happens
Trigger: os.WriteFile(HomeCurrentPlanPath, bytes, 0644) fails — disk full, ~/.plandex missing or unwritable, permission denied on the existing file, or the target path is a directory. Raised from 'plandex cd' / 'plandex new'.
Common situations: Full disk (ENOSPC); ~/.plandex deleted or recreated with wrong ownership while the CLI runs under a different user; read-only home filesystem (diskless/NFS ro); antivirus or sandbox blocking writes to dotfiles.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- error checking if settings-v2.json exists: %v
- error creating directory: %v
- error checking if current-plans-v2.json exists: %v
- error creating plan dir: %v
- error checking if settings-v2.json exists: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f30a3e64da0d3871.
Report an issue: GitHub.