Skip to content

A hand-written [sponsors] enabled = false is undone after one config save and reload #1188

Description

@ianalitis

Source commit: 983b53270 (upstream master, 2026-09-06; repair_frozen_sponsors_optout unchanged)
Upstream: https://github.com/1jehuang/jcode
Binary identity: jcode v0.81.66-dev (0d008c720)
Platform: macOS 26.6.2, arm64

Summary

Writing [sponsors]\nenabled = false by hand into config.toml is respected on
the next load, but the opt-out disappears after any process saves config and a
later load reads it back. Observed twice on this host (2026-09-05 13:xx append,
gone by 22:26; re-appended, would have been lost on the next save).

Cause (from source)

  1. Config::save (crates/jcode-base/src/config/config_file.rs) serializes the
    whole struct. sponsors_is_default (config.rs:837) skips the table only when
    enabled is true, so an opt-out is written back as two keys:
    enabled = false plus the default endpoint.
  2. repair_frozen_sponsors_optout (config_file.rs:79) treats exactly that
    shape, two keys with enabled = false and a default endpoint, as a
    machine-frozen legacy value and resets it to SponsorsConfig::default()
    (enabled) in memory.
  3. The following save omits the now-default table. The user's opt-out is gone.

The heuristic cannot distinguish "hand-written opt-out round-tripped once through
save" from "frozen by the legacy default". Every hand-written opt-out becomes the
former after the first save.

Reproduction

printf '\n[sponsors]\nenabled = false\n' >> ~/.jcode/config.toml
grep -A2 '^\[sponsors\]' ~/.jcode/config.toml   # table absent

Expected

An explicit enabled = false survives save and reload indefinitely.

Proposed fix

Either serialize the opt-out as the single key the user wrote (skip endpoint
when it equals the default), or mark the repair with a one-time migration flag
instead of inferring it from table shape. A regression test: write
[sponsors] enabled = false, load, save, load, assert enabled == false.

Workaround in use

Pair the opt-out with a non-default endpoint, which the heuristic respects:

[sponsors]
enabled = false
endpoint = "http://127.0.0.1:1"

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    autonomous: clearHands-off: unambiguous bug, obvious fix, no decisions. Don't even look - an agent can fully solve.bugSomething isn't workingtriage: reproducibleClear repro + clear fix path

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions