{"record":{"id":"8ec2216ec919b9ab","repo":"plandex-ai/plandex","slug":"error-copying-settings-v","errorCode":null,"errorMessage":"error copying settings: %v","messagePattern":"error copying settings: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/model_settings.go","lineNumber":125,"sourceCode":"\t}\n\n\terr = os.WriteFile(hashPath, []byte(hash), 0644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing hash file: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc ApplyModelSettings(path string, originalSettings *shared.PlanSettings) (*shared.PlanSettings, error) {\n\tjsonData, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading JSON file: %v\", err)\n\t}\n\n\tsettings, err := originalSettings.DeepCopy()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error copying settings: %v\", err)\n\t}\n\n\tclientModelPackRoles, err := schema.ValidateModelPackInlineJSON(jsonData)\n\tif err != nil {\n\t\tterm.StopSpinner()\n\t\tcolor.New(color.Bold, term.ColorHiRed).Println(\"🚨 Error validating JSON file\")\n\t\tfmt.Println(err.Error())\n\t\tos.Exit(1)\n\t}\n\tmodelPackRoles := clientModelPackRoles.ToModelPackSchemaRoles()\n\n\tmodelPackSchema := shared.ModelPackSchema{\n\t\tName:                 \"custom\",\n\t\tDescription:          \"Model pack with custom settings\",\n\t\tModelPackSchemaRoles: modelPackRoles,\n\t}\n\tmodelPack := modelPackSchema.ToModelPack()\n\tsettings.SetCustomModelPack(&modelPack)","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/model_settings.go#L107-L143","documentation":"ApplyModelSettings deep-copies the original PlanSettings so it can attach a custom model pack without mutating the caller's copy. A DeepCopy failure is wrapped as 'error copying settings: %v'. DeepCopy in plandex-shared goes through JSON round-trip marshaling, so failures mean the settings struct could not be serialized/cloned.","triggerScenarios":"originalSettings.DeepCopy() errors — i.e. the PlanSettings (including its model pack) contains data that cannot be JSON-marshaled/unmarshaled, typically after version mismatch or corrupt server payload.","commonSituations":"Settings fetched from a server on a different plandex-shared version with role fields of unexpected shape; a custom model pack assembled programmatically with unsupported values.","solutions":["Inspect the wrapped %v message to find the field that failed to copy","Align CLI and server versions so PlanSettings round-trips cleanly","Re-fetch settings via GetSettings/GetOrgDefaultSettings instead of reusing a possibly stale object","If DeepCopy is failing on benign data, clone manually or update plandex-shared to fix the round-trip"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// smoke-test that DeepCopy will work: the copy is JSON round-trip based\nif _, err := json.Marshal(originalSettings); err != nil {\n    return fmt.Errorf(\"settings not copyable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"updated, err := lib.ApplyModelSettings(path, current)\nif err != nil {\n    if strings.Contains(err.Error(), \"error copying settings\") {\n        // re-fetch settings from server and retry\n    }\n    return err\n}","preventionTips":["Fetch settings fresh via GetSettings before applying","Keep plandex-shared versions aligned across CLI and server","Avoid custom dynamic-typed fields in PlanSettings","Round-trip settings through JSON in tests to catch copy breakage early"],"tags":["go","deepcopy","serialization","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-12T22:17:10.623Z"}