plandex-ai/plandex · error

error reading settings-v2.json: %v

Error message

error reading settings-v2.json: %v

What it means

When os.Stat confirms settings-v2.json exists, the function reads it with os.ReadFile. If the read fails (permissions, file deleted between stat and read, I/O error), it wraps the OS error as 'error reading settings-v2.json: %v'. Note the stat-then-read race: existence at stat time does not guarantee a successful read.

Source

Thrown at app/cli/lib/plans.go:220

		return "", fmt.Errorf("HomePlandexDir not set")
	}

	if CurrentProjectId == "" || HomeCurrentPlanPath == "" {
		return "", fmt.Errorf("no current project")
	}

	v2Path := filepath.Join(fs.HomePlandexDir, CurrentProjectId, planId, "settings-v2.json")

	var settings *types.PlanSettings

	// check if settings-v2.json exists
	_, err := os.Stat(v2Path)
	if err == nil {
		// read settings-v2.json
		var settingsByAccount types.PlanSettingsByAccount
		bytes, err := os.ReadFile(v2Path)
		if err != nil {
			return "", fmt.Errorf("error reading settings-v2.json: %v", err)
		}
		err = json.Unmarshal(bytes, &settingsByAccount)
		if err != nil {
			return "", fmt.Errorf("error unmarshalling settings-v2.json: %v", err)
		}

		settings = settingsByAccount[auth.Current.UserId]
	} else if os.IsNotExist(err) {
		return "main", nil
	} else {
		return "", fmt.Errorf("error checking if settings-v2.json exists: %v", err)
	}

	if settings == nil {
		return "main", nil
	}

	return settings.Branch, nil

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check and fix permissions: chmod u+r (and directory u+rx) on the settings-v2.json path
  2. Verify the path is a regular file, not a directory or broken symlink: ls -l
  3. Recreate the settings file (or delete it — a missing file legitimately defaults the branch to 'main')
  4. Check disk/filesystem health if read fails with an I/O error

Example fix

// before
bytes, err := os.ReadFile(v2Path)
if err != nil { return "", fmt.Errorf("error reading settings-v2.json: %v", err) }
// after (robust)
bytes, err := os.ReadFile(v2Path)
if os.IsNotExist(err) { return "main", nil } // tolerate vanished file
if err != nil { return "", fmt.Errorf("error reading settings-v2.json: %w", err) }
Defensive patterns

Strategy: fallback

Validate before calling

info, err := os.Stat(v2Path)
if err == nil && !info.Mode().IsRegular() {
    return fmt.Errorf("%s is not a regular file", v2Path)
}
if err == nil && info.Mode().Perm()&0400 == 0 {
    return fmt.Errorf("%s is not readable", v2Path)
}

Try / catch

branch, err := getPlanCurrentBranch(planId)
if err != nil && strings.Contains(err.Error(), "error reading settings-v2.json") {
    // file unreadable: fall back to default branch instead of failing the batch
    branch = "main"
}

Prevention

When it happens

Trigger: settings-v2.json exists at HomePlandexDir/CurrentProjectId/planId/ but os.ReadFile fails — permission denied, the file vanished between Stat and ReadFile, disk I/O errors, or the path points to a directory.

Common situations: Running the CLI as a different user than the one who created ~/.plandex; antivirus/backup tools temporarily locking files; a broken symlink; plan directory partially deleted.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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