plandex-ai/plandex · error

error marshalling current plan settings: %v

Error message

error marshalling current plan settings: %v

What it means

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).

Source

Thrown at app/cli/lib/plans.go:150

		return fmt.Errorf("error checking if settings-v2.json exists: %v", err)
	}

	if settingsByAccount == nil {
		settingsByAccount = &types.PlanSettingsByAccount{}
	}

	existingSettings := (*settingsByAccount)[auth.Current.UserId]

	if existingSettings == nil {
		existingSettings = &types.PlanSettings{}
	}

	existingSettings.Branch = branch
	(*settingsByAccount)[auth.Current.UserId] = existingSettings

	bytes, err = json.Marshal(settingsByAccount)
	if err != nil {
		return fmt.Errorf("error marshalling current plan settings: %v", err)
	}

	err = os.WriteFile(path, bytes, 0644)

	if err != nil {
		return fmt.Errorf("error writing current plan settings: %v", err)
	}

	CurrentBranch = branch

	return nil
}

func GetCurrentBranchNamesByPlanId(planIds []string) (map[string]string, error) {
	if fs.HomePlandexDir == "" {
		return nil, fmt.Errorf("HomePlandexDir not set")
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped marshal error to identify the offending field in types.PlanSettings.
  2. Ensure the types package version matches the CLI build (no local modifications adding non-JSON-safe fields).
  3. Add json tags or omit unsupported fields in types.PlanSettings, then rebuild.

Example fix

// before (types package)
type PlanSettings struct {
    Branch string
    Conn   net.Conn // unsupported by json
}

// after
type PlanSettings struct {
    Branch string `json:"branch"`
}
Defensive patterns

Strategy: type-guard

Validate before calling

b, err := json.Marshal(&types.PlanSettings{Branch: branch})
if err != nil {
    return fmt.Errorf("PlanSettings not JSON-serializable: %w", err)
}

Type guard

func marshalable(v any) bool {
    _, err := json.Marshal(v)
    return err == nil
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/cc25c6c9792d9703. Report an issue: GitHub.