plandex-ai/plandex · error

error hashing model pack: %v

Error message

error hashing model pack: %v

What it means

ModelSettingsCheckLocalChanges computes a deterministic hash of the locally edited model-settings.json model pack and compares it with the last saved .hash sidecar to detect local changes. This error is returned when ModelPackSchemaRoles.Hash() (a json.Marshal + SHA-style digest in plandex-shared) fails, meaning the in-memory roles struct could not be serialized for hashing. It is a wrapper; the underlying cause is in the wrapped %v message.

Source

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

	lastSavedHash, err := os.ReadFile(hashPath)
	if err != nil && !os.IsNotExist(err) {
		return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error reading hash file: %v", err)
	}

	localJsonData, err := os.ReadFile(path)
	if err != nil {
		return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error reading JSON file: %v", err)
	}

	var clientModelPackSchemaRoles *shared.ClientModelPackSchemaRoles
	err = json.Unmarshal(localJsonData, &clientModelPackSchemaRoles)
	if err != nil {
		return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error unmarshalling JSON file: %v", err)
	}

	currentHash, err := clientModelPackSchemaRoles.ToModelPackSchemaRoles().Hash()
	if err != nil {
		return ModelSettingsCheckLocalChangesResult{}, fmt.Errorf("error hashing model pack: %v", err)
	}

	modelPackSchemaRoles := clientModelPackSchemaRoles.ToModelPackSchemaRoles()

	return ModelSettingsCheckLocalChangesResult{
		HasLocalChanges:           currentHash != string(lastSavedHash),
		LocalModelPackSchemaRoles: &modelPackSchemaRoles,
	}, nil
}

func WriteModelSettingsFile(path string, originalSettings *shared.PlanSettings) error {
	err := os.MkdirAll(filepath.Dir(path), 0755)
	if err != nil {
		return fmt.Errorf("error creating directory: %v", err)
	}

	modelPackSchemaRoles := originalSettings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped %v cause in the error message and fix the underlying serialization problem
  2. Regenerate the settings file by deleting model-settings.json and its .hash file, then re-saving model settings from the CLI
  3. Upgrade or downgrade the CLI so the CLI and plandex-shared versions match the version that wrote the file
  4. Ensure the JSON file only contains fields the current ClientModelPackSchemaRoles schema understands

Example fix

// before (mismatched/legacy file causes hash failure)
plandex update-model-settings
// error hashing model pack: json: unsupported type: ...
// after
cd <plan dir>; rm ~/.plandex/<planId>/model-settings.json ~/.plandex/<planId>/model-settings.json.hash
plandex update-model-settings  # re-creates a valid file + hash
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify the file parses and its roles marshal cleanly before calling
var roles *shared.ClientModelPackSchemaRoles
if data, err := os.ReadFile(path); err == nil {
    if json.Unmarshal(data, &roles) == nil {
        if _, err := roles.ToModelPackSchemaRoles().Hash(); err != nil {
            // hash will fail — regenerate the settings file first
        }
    }
}

Type guard

func isHashable(roles shared.ModelPackSchemaRoles) bool {
    _, err := roles.Hash()
    return err == nil
}

Try / catch

res, err := lib.ModelSettingsCheckLocalChanges(path)
if err != nil {
    if strings.Contains(err.Error(), "error hashing model pack") {
        // regenerate settings file + hash, then retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling ModelSettingsCheckLocalChanges on a plan's model-settings.json whose parsed ClientModelPackSchemaRoles converts to a ModelPackSchemaRoles containing fields json.Marshal cannot serialize (e.g. invalid custom value types introduced by a schema/version mismatch between the CLI and plandex-shared).

Common situations: Model-settings.json written by a different Plandex version; hand-edited settings files with unexpected role fields; a plandex-shared upgrade changing struct field types so old persisted values no longer marshal cleanly.

Related errors


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