Skip to content

P1: SettingsManager manual property mapping is a bug factory and should use an immutable record #555

@QQSHI13

Description

@QQSHI13

Problem

SettingsManager is a mutable god object with ~100 public properties. Every load/save cycle requires manual mapping in three places: the property declaration, the Load() method, and ToSettingsData(). This is extremely error-prone — it is easy to add a property and forget to persist it, causing silent data loss.

Additionally, Load() parses JSON twice: once via JsonDocument for legacy credential migration, then again via SettingsData.FromJson.

Impact

  • Adding a new setting requires manual edits in 3+ locations.
  • Silent bugs where the UI shows a setting but it never round-trips to disk (or vice versa).
  • Legacy migration logic is mixed with active persistence logic.

Suggested fix

  1. Make SettingsData the single source of truth — an immutable record with init-only properties.
  2. Have SettingsManager hold a private SettingsData _data field and expose accessors that delegate to it:
    public string GatewayUrl
    {
        get => _data.GatewayUrl;
        set => _data = _data with { GatewayUrl = value };
    }
  3. Replace the giant manual Load() / ToSettingsData() copy blocks with a single JsonSerializer.Deserialize<SettingsData>(json) call, using fallback defaults (data ?? SettingsData.Default).
  4. Use a custom JsonConverter for DPAPI-protected secrets so encryption is transparent to the model.

Files

  • src/OpenClaw.Tray.WinUI/Services/SettingsManager.cs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions