{"record":{"id":"87f1a58a388d306a","repo":"plandex-ai/plandex","slug":"error-hashing-model-pack-v","errorCode":null,"errorMessage":"error hashing model pack: %v","messagePattern":"error hashing model pack: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/model_settings.go","lineNumber":62,"sourceCode":"\tlastSavedHash, err := os.ReadFile(hashPath)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn ModelSettingsCheckLocalChangesResult{}, fmt.Errorf(\"error reading hash file: %v\", err)\n\t}\n\n\tlocalJsonData, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn ModelSettingsCheckLocalChangesResult{}, fmt.Errorf(\"error reading JSON file: %v\", err)\n\t}\n\n\tvar clientModelPackSchemaRoles *shared.ClientModelPackSchemaRoles\n\terr = json.Unmarshal(localJsonData, &clientModelPackSchemaRoles)\n\tif err != nil {\n\t\treturn ModelSettingsCheckLocalChangesResult{}, fmt.Errorf(\"error unmarshalling JSON file: %v\", err)\n\t}\n\n\tcurrentHash, err := clientModelPackSchemaRoles.ToModelPackSchemaRoles().Hash()\n\tif err != nil {\n\t\treturn ModelSettingsCheckLocalChangesResult{}, fmt.Errorf(\"error hashing model pack: %v\", err)\n\t}\n\n\tmodelPackSchemaRoles := clientModelPackSchemaRoles.ToModelPackSchemaRoles()\n\n\treturn ModelSettingsCheckLocalChangesResult{\n\t\tHasLocalChanges:           currentHash != string(lastSavedHash),\n\t\tLocalModelPackSchemaRoles: &modelPackSchemaRoles,\n\t}, nil\n}\n\nfunc WriteModelSettingsFile(path string, originalSettings *shared.PlanSettings) error {\n\terr := os.MkdirAll(filepath.Dir(path), 0755)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating directory: %v\", err)\n\t}\n\n\tmodelPackSchemaRoles := originalSettings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/model_settings.go#L44-L80","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Read the wrapped %v cause in the error message and fix the underlying serialization problem","Regenerate the settings file by deleting model-settings.json and its .hash file, then re-saving model settings from the CLI","Upgrade or downgrade the CLI so the CLI and plandex-shared versions match the version that wrote the file","Ensure the JSON file only contains fields the current ClientModelPackSchemaRoles schema understands"],"exampleFix":"// before (mismatched/legacy file causes hash failure)\nplandex update-model-settings\n// error hashing model pack: json: unsupported type: ...\n// after\ncd <plan dir>; rm ~/.plandex/<planId>/model-settings.json ~/.plandex/<planId>/model-settings.json.hash\nplandex update-model-settings  # re-creates a valid file + hash","handlingStrategy":"try-catch","validationCode":"// Go: verify the file parses and its roles marshal cleanly before calling\nvar roles *shared.ClientModelPackSchemaRoles\nif data, err := os.ReadFile(path); err == nil {\n    if json.Unmarshal(data, &roles) == nil {\n        if _, err := roles.ToModelPackSchemaRoles().Hash(); err != nil {\n            // hash will fail — regenerate the settings file first\n        }\n    }\n}","typeGuard":"func isHashable(roles shared.ModelPackSchemaRoles) bool {\n    _, err := roles.Hash()\n    return err == nil\n}","tryCatchPattern":"res, err := lib.ModelSettingsCheckLocalChanges(path)\nif err != nil {\n    if strings.Contains(err.Error(), \"error hashing model pack\") {\n        // regenerate settings file + hash, then retry\n    }\n    return err\n}","preventionTips":["Keep CLI and plandex-shared versions in lockstep","Never hand-edit model-settings.json with unknown fields","Delete the .json/.hash pair and re-save after upgrades","Validate the JSON against the current schema before comparing hashes"],"tags":["go","serialization","hashing","model-settings"],"backgroundTag":"struct-marshal-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}