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

  1. Check free space: df -h ~ and clean up if the disk is full.
  2. Check ownership/permissions of ~/.plandex and the file: ls -ld ~/.plandex ~/.plandex/current-plans-v2.json; chown/chmod as needed.
  3. If the path is a directory or bad symlink, remove it so WriteFile can create the file.
  4. 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

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


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