plandex-ai/plandex · error

error reading settings file: %v

Error message

error reading settings file: %v

What it means

GetPlanSettings reads a plan's settings file from disk; when the file exists but cannot be read (I/O error other than not-exists), the read error is wrapped with this message. It signals a filesystem-level failure, not a missing-settings condition — a missing file returns a default PlanSettings instead.

Source

Thrown at app/server/db/settings_helpers.go:58

			return nil, fmt.Errorf("error getting org default settings: %v", err)
		}

		if defaultSettings != nil {
			log.Printf("GetPlanSettings - found org default settings for plan %s", plan.Id)
			return defaultSettings, nil
		} else {
			log.Printf("GetPlanSettings - no org default settings found for plan %s", plan.Id)
		}

		log.Println("GetPlanSettings - no default settings found, returning default settings object")
		// if it doesn't exist, return default settings object
		settings = &shared.PlanSettings{
			UpdatedAt:     plan.CreatedAt,
			ModelPackName: shared.DefaultModelPack.Name,
		}
		return settings, nil
	} else if err != nil {
		return nil, fmt.Errorf("error reading settings file: %v", err)
	}

	log.Printf("GetPlanSettings - settings found in file")

	err = json.Unmarshal(bytes, &settings)

	if err != nil {
		return nil, fmt.Errorf("error unmarshalling settings: %v", err)
	}

	return settings, nil
}

func StorePlanSettings(plan *Plan, settings shared.PlanSettings) error {
	planDir := getPlanDir(plan.OrgId, plan.Id)
	settingsPath := filepath.Join(planDir, "settings.json")

	settings.UpdatedAt = time.Now()

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check file permissions/ownership on the plan settings file and fix with chown/chmod so the server process can read it
  2. Verify the settings file path is a regular file, not a directory or symlink to a missing target
  3. Log the wrapped underlying error (%v of err) to identify the exact syscall failure
  4. If on a mounted volume, confirm the mount is healthy and the file exists
  5. Delete or restore the corrupted settings file so a fresh default is written

Example fix

// before
return nil, fmt.Errorf("error reading settings file: %v", err)
// after
return nil, fmt.Errorf("error reading settings file %s: %w", settingsPath, err) // include path + %w for unwrapping
Defensive patterns

Strategy: fallback

Validate before calling

// before calling
if _, err := os.Stat(settingsPath); err != nil {
    if os.IsNotExist(err) { return defaultPlanSettings(), nil } // missing file is fine
    // permission or other I/O problem surfaces here
}

Try / catch

settings, err := GetPlanSettings(ctx, plan)
if err != nil {
    log.Printf("settings read failed: %v — falling back to defaults", err)
    settings = &shared.PlanSettings{UpdatedAt: plan.CreatedAt, ModelPackName: shared.DefaultModelPack.Name}
}

Prevention

When it happens

Trigger: os.ReadFile on the plan settings file returns an error other than os.IsNotExist — e.g. permission denied, path is a directory, or transient I/O failure while GetPlanSettings is called via LoadContexts, UpdateContexts, loadContexts, TellPlanHandler, or BuildPlanHandler.

Common situations: Settings file created by a different user/uid (permission mismatch after running app under another account), settings file corrupted by concurrent writers leaving it unreadable, or container volume mount issues.

Related errors


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