plandex-ai/plandex · error

error marshalling current plan: %v

Error message

error marshalling current plan: %v

What it means

After updating the in-memory map with the new current plan id for auth.Current.UserId, WriteCurrentPlan serializes it with json.Marshal. Failure here means the CurrentPlanSettingsByAccount value could not be encoded (e.g. a map key that is not a string or an unsupported value type), so nothing is written to disk.

Source

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

			return fmt.Errorf("error unmarshalling current-plans-v2.json: %v", err)
		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("error checking if current-plans-v2.json exists: %v", err)
	}

	if currentPlanSettingsByAccount == nil {
		currentPlanSettingsByAccount = &types.CurrentPlanSettingsByAccount{}
	}

	settings := types.CurrentPlanSettings{
		Id: id,
	}

	(*currentPlanSettingsByAccount)[auth.Current.UserId] = &settings

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

	err = os.WriteFile(HomeCurrentPlanPath, bytes, 0644)
	if err != nil {
		return fmt.Errorf("error writing current plan: %v", err)
	}

	CurrentPlanId = id

	return nil
}

func ClearCurrentPlan() error {
	if fs.HomePlandexDir == "" {
		return fmt.Errorf("HomePlandexDir not set")
	}

	if CurrentProjectId == "" || HomeCurrentPlanPath == "" {

View on GitHub (pinned to e2d772072e)

Solutions

  1. Verify the types.CurrentPlanSettingsByAccount / CurrentPlanSettings structs only contain JSON-encodable types in your build.
  2. Rebuild the CLI from the matching tag so types match the released schema (go install ./... or the release binary).
  3. Move the corrupt state aside (mv ~/.plandex/current-plans-v2.json{,.bak}) and retry so the map starts empty.
  4. If you modified the types package, add MarshalJSON or change the offending field to an encodable type.

Example fix

// before: unsupported field type in types
settings := types.CurrentPlanSettings{Id: id, Callback: func(){}}
// error marshalling current plan: json: unsupported type: func()

// after: store only encodable data
settings := types.CurrentPlanSettings{Id: id}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the state you feed the lib is encodable before calling
if b, err := json.Marshal(existingState); err != nil {
	return fmt.Errorf("state not encodable, refusing to update plan: %v", err)
} else { _ = b }

Type guard

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

Try / catch

if err := lib.WriteCurrentPlan(id); err != nil {
	if strings.Contains(err.Error(), "error marshalling current plan") {
		// fall back: rebuild state from scratch
		os.Remove(homePlansPath)
		err = lib.WriteCurrentPlan(id)
	}
}

Prevention

When it happens

Trigger: json.Marshal(currentPlanSettingsByAccount) returns an error just before the os.WriteFile call — practically only when the map or CurrentPlanSettings struct contains values json cannot encode (invalid UTF-8 keys, unsupported types). Raised from 'plandex cd' / 'plandex new'.

Common situations: A hand-patched or version-mismatched types package with an unsupported field type; corrupted account-id map keys from a modified state file; custom build where CurrentPlanSettings gained a non-encodable field.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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