plandex-ai/plandex · error

error reading projectId file: %s

Error message

error reading projectId file: %s

What it means

Fires in GetParentProjectIdsWithPaths when os.ReadFile fails on projects-v2.json inside a discovered .plandex directory while walking up from the current dir. The settings file exists (os.Stat succeeded) but is unreadable — permissions or a race with deletion.

Source

Thrown at app/cli/fs/projects.go:24

	"fmt"
	"os"
	"path/filepath"
	"plandex-cli/term"
	"plandex-cli/types"
	"strings"
)

func GetParentProjectIdsWithPaths(currentUserId string) ([][2]string, error) {
	var parentProjectIds [][2]string
	currentDir := filepath.Dir(Cwd)

	for currentDir != "/" {
		plandexDir := findPlandex(currentDir)
		projectSettingsPath := filepath.Join(plandexDir, "projects-v2.json")
		if _, err := os.Stat(projectSettingsPath); err == nil {
			bytes, err := os.ReadFile(projectSettingsPath)
			if err != nil {
				return nil, fmt.Errorf("error reading projectId file: %s", err)
			}

			var settingsByAccount types.CurrentProjectSettingsByAccount
			err = json.Unmarshal(bytes, &settingsByAccount)

			if err != nil {
				term.OutputErrorAndExit("error unmarshalling projects-v2.json: %v", err)
			}

			settings := settingsByAccount[currentUserId]

			if settings == nil {
				return parentProjectIds, nil
			}

			projectId := string(settings.Id)
			parentProjectIds = append(parentProjectIds, [2]string{currentDir, projectId})
		}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Fix permissions on the ancestor .plandex/projects-v2.json (chmod/chown so the current user can read it)
  2. If projects-v2.json is a directory or corrupt, remove or repair it (delete stale ancestor project dirs)
  3. Copy the project to a writable location if on a read-only mount
  4. Identify the exact syscall error from the wrapped %s value

Example fix

// before
ls -l /parent/.plandex/projects-v2.json  # -rw------- root
// after
sudo chown $(whoami) /parent/.plandex/projects-v2.json && chmod 600 /parent/.plandex/projects-v2.json
Defensive patterns

Strategy: try-catch

Validate before calling

p := filepath.Join(plandexDir, "projects-v2.json")
if f, err := os.Open(p); err != nil {
    return fmt.Errorf("cannot read %s: %w", p, err)
} else {
    f.Close()
}

Try / catch

ids, err := GetParentProjectIdsWithPaths(startDir)
if err != nil {
    if errors.Is(err, os.ErrPermission) {
        ids = nil // proceed without ancestor project settings
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: os.ReadFile on an existing projects-v2.json fails — permission denied on the file, it is a directory named projects-v2.json, or an I/O error occurs during read.

Common situations: Ancestor .plandex dir created by root or another user with restrictive permissions; corrupted filesystem; projects-v2.json replaced by a directory or a locked file on Windows.

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/4840d525f2e18be9. Report an issue: GitHub.