plandex-ai/plandex · error
error checking if settings-v2.json exists: %v
Error message
error checking if settings-v2.json exists: %v
What it means
When reading settings-v2.json, WriteCurrentBranch tolerates os.IsNotExist but treats any other read error (permission denied, path is a directory, I/O error) as fatal, wrapping it as 'error checking if settings-v2.json exists: %v'. This distinguishes 'no settings yet' from 'cannot even stat/read the file'.
Source
Thrown at app/cli/lib/plans.go:132
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
return fmt.Errorf("error creating plan dir: %v", err)
}
path := filepath.Join(dir, "settings-v2.json")
var settingsByAccount *types.PlanSettingsByAccount
bytes, err := os.ReadFile(path)
if err == nil {
err = json.Unmarshal(bytes, &settingsByAccount)
if err != nil {
return fmt.Errorf("error unmarshalling settings-v2.json: %v", err)
}
} else if !os.IsNotExist(err) {
return fmt.Errorf("error checking if settings-v2.json exists: %v", err)
}
if settingsByAccount == nil {
settingsByAccount = &types.PlanSettingsByAccount{}
}
existingSettings := (*settingsByAccount)[auth.Current.UserId]
if existingSettings == nil {
existingSettings = &types.PlanSettings{}
}
existingSettings.Branch = branch
(*settingsByAccount)[auth.Current.UserId] = existingSettings
bytes, err = json.Marshal(settingsByAccount)
if err != nil {
return fmt.Errorf("error marshalling current plan settings: %v", err)View on GitHub (pinned to e2d772072e)
Solutions
- Read the wrapped OS error; for permission issues run chmod u+rw (or chown back to your user) on the file/dir.
- If settings-v2.json is a directory, remove/rename it so the CLI can write a file there.
- Check filesystem health (mount flags, dmesg) if errors indicate I/O problems.
Example fix
// error: ... permission denied $ ls -la ~/.plandex/<project>/<plan>/settings-v2.json $ sudo chown -R $USER ~/.plandex && chmod -R u+rw ~/.plandex $ plandex checkout main
Defensive patterns
Strategy: try-catch
Validate before calling
path := filepath.Join(fs.HomePlandexDir, lib.CurrentProjectId, lib.CurrentPlanId, "settings-v2.json")
if _, err := os.Stat(path); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot access settings-v2.json: %w", err)
} Try / catch
if err := lib.WriteCurrentBranch(branch); err != nil {
if strings.Contains(err.Error(), "error checking if settings-v2.json exists") {
if errors.Is(err, os.ErrPermission) {
return fmt.Errorf("fix ownership: chown -R $USER ~/.plandex")
}
return err
}
return nil
} Prevention
- Avoid sudo runs of the CLI, which change file ownership.
- Ensure nothing (backup tools, mistakes) creates a directory named settings-v2.json.
- Check mount flags on the home filesystem before running state-mutating commands.
When it happens
Trigger: os.ReadFile on settings-v2.json fails with a non-ENOENT error: permission denied, the path exists as a directory named settings-v2.json, symlink loop, or underlying disk I/O error.
Common situations: settings-v2.json owned by root after a sudo run; someone created a directory named settings-v2.json; filesystem mounted read-only or failing; backup/restore tools leaving wrong permissions.
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 creating plan dir: %v
- no project root found
- error walking directory: %s
- failed to check if %s exists: %s
- failed to read %s: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f26224995a09e02e.
Report an issue: GitHub.