plandex-ai/plandex · error

error saving model settings hash: %v

Error message

error saving model settings hash: %v

What it means

After merging the custom model pack into the settings copy, ApplyModelSettings calls SaveModelPackRolesHash to refresh the <path>.hash sidecar so future local-change detection compares against the just-applied pack. Any failure is re-wrapped as 'error saving model settings hash: %v'. At this point validation already passed and settings were updated in memory, but the new settings were not persisted to a hash.

Source

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

	if err != nil {
		term.StopSpinner()
		color.New(color.Bold, term.ColorHiRed).Println("🚨 Error validating JSON file")
		fmt.Println(err.Error())
		os.Exit(1)
	}
	modelPackRoles := clientModelPackRoles.ToModelPackSchemaRoles()

	modelPackSchema := shared.ModelPackSchema{
		Name:                 "custom",
		Description:          "Model pack with custom settings",
		ModelPackSchemaRoles: modelPackRoles,
	}
	modelPack := modelPackSchema.ToModelPack()
	settings.SetCustomModelPack(&modelPack)

	err = SaveModelPackRolesHash(path, &modelPackRoles)
	if err != nil {
		return nil, fmt.Errorf("error saving model settings hash: %v", err)
	}

	return settings, nil
}

func SaveLatestPlanModelSettingsIfNeeded() (bool, error) {
	path := GetPlanModelSettingsPath(CurrentPlanId)
	jsonData, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, fmt.Errorf("error reading JSON file: %v", err)
	}

	var clientModelPackSchemaRoles *shared.ClientModelPackSchemaRoles
	err = json.Unmarshal(jsonData, &clientModelPackSchemaRoles)
	if err != nil {

View on GitHub (pinned to e2d772072e)

Solutions

  1. Fix permissions/ownership on the .hash file and its directory (e.g. chown back to your user if a sudo run created it as root)
  2. Check the wrapped cause; free disk space if ENOSPC
  3. Delete model-settings.json + model-settings.json.hash and re-run the apply/sync flow
  4. Match CLI and plandex-shared versions if the underlying Hash() call failed

Example fix

// before
-rw-r--r-- 1 root root model-settings.json.hash  # owned by root after sudo run
// after
sudo chown "$USER:$USER" ~/.plandex/<planId>/model-settings.json*
Defensive patterns

Strategy: try-catch

Validate before calling

hashPath := path + ".hash"
if f, err := os.OpenFile(hashPath, os.O_WRONLY|os.O_CREATE, 0o644); err != nil {
    return fmt.Errorf("hash path not writable: %w", err)
} else { f.Close() }

Try / catch

updated, err := lib.ApplyModelSettings(path, current)
if err != nil {
    if strings.Contains(err.Error(), "error saving model settings hash") {
        // settings updated in memory but hash stale: fix permissions,
        // delete .json+.hash pair, re-run apply/sync
    }
    return err
}

Prevention

When it happens

Trigger: SaveModelPackRolesHash fails from either ModelPackSchemaRoles.Hash() marshaling failure or os.WriteFile on the .hash path failing (permissions, read-only mount, disk full).

Common situations: Read-only ~/.plandex after applying settings; hash file owned by root after a sudo-run CLI session; plandex-shared Hash() failure from an incompatible schema version.

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