{"record":{"id":"ee56a62b0175b10f","repo":"plandex-ai/plandex","slug":"error-unmarshalling-settings-v2-json-v","errorCode":null,"errorMessage":"error unmarshalling settings-v2.json: %v","messagePattern":"error unmarshalling settings-v2\\.json: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/plans.go","lineNumber":129,"sourceCode":"\t}\n\n\tdir := filepath.Join(fs.HomePlandexDir, CurrentProjectId, CurrentPlanId)\n\n\terr := os.MkdirAll(dir, os.ModePerm)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating plan dir: %v\", err)\n\t}\n\n\tpath := filepath.Join(dir, \"settings-v2.json\")\n\n\tvar settingsByAccount *types.PlanSettingsByAccount\n\n\tbytes, err := os.ReadFile(path)\n\tif err == nil {\n\t\terr = json.Unmarshal(bytes, &settingsByAccount)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error unmarshalling settings-v2.json: %v\", err)\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\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","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/plans.go#L111-L147","documentation":"WriteCurrentBranch reads the plan's settings-v2.json and unmarshals it into types.PlanSettingsByAccount. If the file exists but its contents are not valid JSON (or don't match the expected shape), json.Unmarshal fails and the error is wrapped as 'error unmarshalling settings-v2.json: %v'. A missing file is intentionally tolerated and treated as empty settings.","triggerScenarios":"os.ReadFile succeeds but json.Unmarshal fails: file is empty/truncated, contains an array or string instead of an object keyed by account id, was hand-edited with syntax errors, or was written by an incompatible CLI version with a different schema.","commonSituations":"Manual editing of settings-v2.json breaking JSON syntax; an interrupted write (crash/power loss) leaving a truncated file; migrating from an older settings format whose JSON shape no longer unmarshals into PlanSettingsByAccount.","solutions":["Validate the file: run the wrapped JSON error's line/column through a JSON linter, or `python3 -m json.tool <path>` to find the syntax problem.","If the content is unrecoverable or from an old format, back it up and delete settings-v2.json — WriteCurrentBranch tolerates a missing file and will recreate it.","Avoid hand-editing; let the CLI rewrite the file by re-running the checkout/branch command after cleanup."],"exampleFix":"$ cat ~/.plandex/<project>/<plan>/settings-v2.json | python3 -m json.tool\n// invalid -> fix syntax, or:\n$ mv settings-v2.json settings-v2.json.bak\n$ plandex checkout main  # recreates settings-v2.json","handlingStrategy":"try-catch","validationCode":"path := filepath.Join(fs.HomePlandexDir, lib.CurrentProjectId, lib.CurrentPlanId, \"settings-v2.json\")\nif b, err := os.ReadFile(path); err == nil {\n    var v map[string]any\n    if err := json.Unmarshal(b, &v); err != nil {\n        return fmt.Errorf(\"settings-v2.json is corrupt: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := lib.WriteCurrentBranch(branch); err != nil {\n    if strings.Contains(err.Error(), \"error unmarshalling settings-v2.json\") {\n        os.Rename(path, path+\".corrupt\") // archive and let CLI recreate\n        return lib.WriteCurrentBranch(branch)\n    }\n    return err\n}","preventionTips":["Never hand-edit settings-v2.json; use CLI commands.","Keep a backup before manual state surgery and restore it if JSON validation fails.","After crashes or power loss, validate ~/.plandex JSON files before further commands."],"tags":["go","json","filesystem","corruption"],"backgroundTag":"json-parse-error","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"}