plandex-ai/plandex · error

error writing model settings file: %v

Error message

error writing model settings file: %v

What it means

When the local hash differs from the server hash, WriteModelSettingsFile(path, settings) overwrites the local file with the server settings. If that write fails (permission, serialization, or rename failure inside the helper), the error is wrapped as this message. The function then aborts with the local file left stale.

Source

Thrown at app/cli/lib/model_settings.go:192

	}

	settings, apiErr := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
	if apiErr != nil {
		return false, fmt.Errorf("error getting settings: %v", apiErr)
	}

	serverHash, err := settings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles.Hash()
	if err != nil {
		return false, fmt.Errorf("error hashing model pack: %v", err)
	}

	if localHash == serverHash {
		return false, nil
	}

	err = WriteModelSettingsFile(path, settings)
	if err != nil {
		return false, fmt.Errorf("error writing model settings file: %v", err)
	}

	return true, nil
}

// save settings in file to server
func SyncPlanModelSettings() error {
	settings, err := api.Client.GetSettings(CurrentPlanId, CurrentBranch)
	if err != nil {
		return fmt.Errorf("error getting settings: %v", err)
	}

	updatedSettings, apiErr := ApplyModelSettings(GetPlanModelSettingsPath(CurrentPlanId), settings)
	if apiErr != nil {
		return fmt.Errorf("error applying model settings: %v", err)
	}

	res, updateErr := api.Client.UpdateSettings(CurrentPlanId, CurrentBranch, shared.UpdateSettingsRequest{

View on GitHub (pinned to e2d772072e)

Solutions

  1. Fix permissions on the settings file and its directory: chown to the current user and ensure write access (chmod u+w).
  2. Check disk space (df -h) and free space if the filesystem is full.
  3. Ensure the parent directory returned by GetPlanModelSettingsPath exists (mkdir -p).
  4. If marshaling fails (inner error mentions json), update the CLI so WriteModelSettingsFile supports the server settings schema.

Example fix

// before
err = WriteModelSettingsFile(path, settings)
if err != nil {
    return false, fmt.Errorf("error writing model settings file: %v", err)
}
// after: ensure the directory exists before writing
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
    return false, fmt.Errorf("error creating settings dir: %w", err)
}
if err := WriteModelSettingsFile(path, settings); err != nil {
    return false, fmt.Errorf("error writing model settings file: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

path := lib.GetPlanModelSettingsPath(planID)
dir := filepath.Dir(path)
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
    os.MkdirAll(dir, 0o755)
}
if err := unix.Access(path, unix.W_OK); err != nil && os.Getenv("SKIP_CHECK") == "" {
    return fmt.Errorf("settings file not writable: %w", err)
}

Type guard

func writable(path string) bool {
    f, err := os.OpenFile(path, os.O_WRONLY, 0)
    if err == nil { f.Close(); return true }
    return false
}

Try / catch

updated, err := lib.SaveLatestPlanModelSettingsIfNeeded()
if err != nil && strings.Contains(err.Error(), "error writing model settings file") {
    log.Warnf("could not persist server settings locally (permissions/disk?): %v", err)
    // proceed; local file stays stale and will retry next run
    return nil
}

Prevention

When it happens

Trigger: WriteModelSettingsFile fails: the settings file or its directory is read-only or owned by another user, the disk is full, settings cannot be marshaled to JSON, or the parent directory does not exist.

Common situations: Running the CLI as a different user than the one who owns the settings file (root vs user); read-only home mount in a container; full disk; settings directory deleted while the CLI was running.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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