{"record":{"id":"9a18f4e36a80925b","repo":"plandex-ai/plandex","slug":"error-marshalling-model-pack-v","errorCode":null,"errorMessage":"error marshalling model pack: %v","messagePattern":"error marshalling model pack: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/model_settings.go","lineNumber":85,"sourceCode":"\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\n\tclientModelPackRoles := modelPackSchemaRoles.ToClientModelPackSchemaRoles()\n\n\tbytes, err := json.MarshalIndent(clientModelPackRoles, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling model pack: %v\", err)\n\t}\n\n\terr = os.WriteFile(path, bytes, 0644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing JSON file: %v\", err)\n\t}\n\n\terr = SaveModelPackRolesHash(path, &modelPackSchemaRoles)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error saving model pack roles hash: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc SaveModelPackRolesHash(basePath string, serverModelPack *shared.ModelPackSchemaRoles) error {\n\thashPath := basePath + \".hash\"\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/model_settings.go#L67-L103","documentation":"WriteModelSettingsFile serializes the plan's model pack roles with json.MarshalIndent before writing model-settings.json. This error wraps a json.Marshal failure. Because ClientModelPackSchemaRoles consists of plain JSON-friendly structs, this rarely fails unless the struct contents are corrupt or a custom MarshalJSON implementation errors.","triggerScenarios":"json.MarshalIndent(clientModelPackRoles) returns an error — e.g. an unsupported type or a custom MarshalJSON on a role field failing due to invalid model role data in originalSettings.GetModelPack().","commonSituations":"A server-supplied settings payload with unexpected role values after a plandex-shared version change; programmatically constructed PlanSettings with fields that cannot be marshaled.","solutions":["Inspect the wrapped %v message for the exact field and type that failed to marshal","Ensure the CLI and server/plandex-shared versions match so GetModelPack() returns schema-conformant roles","Re-fetch settings from the server (GetSettings) instead of using a locally mutated PlanSettings","Report/fix any custom MarshalJSON implementation that errors on valid data"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure the model pack round-trips through JSON before writing\nif _, err := json.Marshal(settings.GetModelPack().ToModelPackSchema().ModelPackSchemaRoles); err != nil {\n    return fmt.Errorf(\"settings not serializable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := lib.WriteModelSettingsFile(path, settings); err != nil {\n    if strings.Contains(err.Error(), \"error marshalling model pack\") {\n        // re-fetch settings from server and retry with fresh data\n    }\n    return err\n}","preventionTips":["Keep CLI and server/plandex-shared versions aligned","Build custom model packs only from schema-defined types","Re-fetch settings rather than mutating long-lived copies","Test MarshalIndent on your roles before persisting in custom tooling"],"tags":["go","json","serialization","model-pack"],"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-14T00:17:10.932Z"}