{"record":{"id":"cc25c6c9792d9703","repo":"plandex-ai/plandex","slug":"error-marshalling-current-plan-settings-v","errorCode":null,"errorMessage":"error marshalling current plan settings: %v","messagePattern":"error marshalling current plan settings: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/plans.go","lineNumber":150,"sourceCode":"\t\treturn fmt.Errorf(\"error checking if settings-v2.json exists: %v\", err)\n\t}\n\n\tif settingsByAccount == nil {\n\t\tsettingsByAccount = &types.PlanSettingsByAccount{}\n\t}\n\n\texistingSettings := (*settingsByAccount)[auth.Current.UserId]\n\n\tif existingSettings == nil {\n\t\texistingSettings = &types.PlanSettings{}\n\t}\n\n\texistingSettings.Branch = branch\n\t(*settingsByAccount)[auth.Current.UserId] = existingSettings\n\n\tbytes, err = json.Marshal(settingsByAccount)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling current plan settings: %v\", err)\n\t}\n\n\terr = os.WriteFile(path, bytes, 0644)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing current plan settings: %v\", err)\n\t}\n\n\tCurrentBranch = branch\n\n\treturn nil\n}\n\nfunc GetCurrentBranchNamesByPlanId(planIds []string) (map[string]string, error) {\n\tif fs.HomePlandexDir == \"\" {\n\t\treturn nil, fmt.Errorf(\"HomePlandexDir not set\")\n\t}\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/plans.go#L132-L168","documentation":"After updating the per-account branch, WriteCurrentBranch re-marshals the whole types.PlanSettingsByAccount map with json.Marshal. Marshal of a plain map/struct of strings essentially cannot fail with normal data, so this 'error marshalling current plan settings: %v' indicates deeply unexpected state — e.g. an unsupported value that cannot serialize (channels, funcs, or cyclic structures if the type ever grows such fields).","triggerScenarios":"json.Marshal(settingsByAccount) returns an error — practically only if types.PlanSettingsByAccount / PlanSettings contains a value json cannot encode (unsupported type, cycle). Ordinary string branch data cannot trigger this.","commonSituations":"Custom or locally patched versions of types.PlanSettings with non-serializable fields; a version mismatch where the types package was modified without compatible json tags.","solutions":["Inspect the wrapped marshal error to identify the offending field in types.PlanSettings.","Ensure the types package version matches the CLI build (no local modifications adding non-JSON-safe fields).","Add json tags or omit unsupported fields in types.PlanSettings, then rebuild."],"exampleFix":"// before (types package)\ntype PlanSettings struct {\n    Branch string\n    Conn   net.Conn // unsupported by json\n}\n\n// after\ntype PlanSettings struct {\n    Branch string `json:\"branch\"`\n}","handlingStrategy":"type-guard","validationCode":"b, err := json.Marshal(&types.PlanSettings{Branch: branch})\nif err != nil {\n    return fmt.Errorf(\"PlanSettings not JSON-serializable: %w\", err)\n}","typeGuard":"func marshalable(v any) bool {\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Keep only JSON-safe fields (strings, ints, maps) in types.PlanSettings with explicit json tags.","Add a unit test that marshals a fully populated PlanSettingsByAccount on every types change.","Avoid locally patching the types package without checking serialization."],"tags":["go","json","serialization"],"backgroundTag":"json-marshal-unsupported-type","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"}