What is wrong.Load accepts any JSON object. A state file without the domains, hostnames, ports and certificates sections loads with nil maps, and the first SetDomainState (or SetHostnameState, SetPortState, SetCertificateState) panics with assignment to entry in nil map. The panic is in the watcher goroutine, so the process dies, and dies again at every restart until the file is fixed.
Where (at e8b4006): internal/state/state.go, Load lines 210-230 (s.snapshot = &snapshot with whatever maps the file had); SetDomainState line 289 and the other setters assign into them.
Scenario. An operator resets the state by writing {} or {"version": 1} to state.json, or hand-edits the file and drops a section (the trial run in #260 edits it between restarts). Confirmed: loading a file holding {} and then calling SetDomainState panics with assignment to entry in nil map.
Correct. A state file with a missing section loads as if the section were empty, as a missing file loads as empty state (README, Monitoring Lifecycle: "If no state file exists, start with empty state"). Load fills in each nil map after parsing.
Done when: loading {}, and a file missing any one section, gives an empty map for each missing section and the first check runs; a test covers both.
Severity: minor
Model: fable-5-1
**What is wrong.** `Load` accepts any JSON object. A state file without the `domains`, `hostnames`, `ports` and `certificates` sections loads with nil maps, and the first `SetDomainState` (or `SetHostnameState`, `SetPortState`, `SetCertificateState`) panics with `assignment to entry in nil map`. The panic is in the watcher goroutine, so the process dies, and dies again at every restart until the file is fixed.
**Where** (at `e8b4006`): `internal/state/state.go`, `Load` lines 210-230 (`s.snapshot = &snapshot` with whatever maps the file had); `SetDomainState` line 289 and the other setters assign into them.
**Scenario.** An operator resets the state by writing `{}` or `{"version": 1}` to `state.json`, or hand-edits the file and drops a section (the trial run in https://git.eeqj.de/sneak/dnswatcher/issues/260 edits it between restarts). Confirmed: loading a file holding `{}` and then calling `SetDomainState` panics with `assignment to entry in nil map`.
**Correct.** A state file with a missing section loads as if the section were empty, as a missing file loads as empty state (README, Monitoring Lifecycle: "If no state file exists, start with empty state"). `Load` fills in each nil map after parsing.
**Done when:** loading `{}`, and a file missing any one section, gives an empty map for each missing section and the first check runs; a test covers both.
Severity: minor
Model: fable-5-1
clawbot
added this to the 1.0 milestone 2026-10-13 12:32:08 +02:00
clawbot
self-assigned this 2026-10-13 12:32:08 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What is wrong.
Loadaccepts any JSON object. A state file without thedomains,hostnames,portsandcertificatessections loads with nil maps, and the firstSetDomainState(orSetHostnameState,SetPortState,SetCertificateState) panics withassignment to entry in nil map. The panic is in the watcher goroutine, so the process dies, and dies again at every restart until the file is fixed.Where (at
e8b4006):internal/state/state.go,Loadlines 210-230 (s.snapshot = &snapshotwith whatever maps the file had);SetDomainStateline 289 and the other setters assign into them.Scenario. An operator resets the state by writing
{}or{"version": 1}tostate.json, or hand-edits the file and drops a section (the trial run in #260 edits it between restarts). Confirmed: loading a file holding{}and then callingSetDomainStatepanics withassignment to entry in nil map.Correct. A state file with a missing section loads as if the section were empty, as a missing file loads as empty state (README, Monitoring Lifecycle: "If no state file exists, start with empty state").
Loadfills in each nil map after parsing.Done when: loading
{}, and a file missing any one section, gives an empty map for each missing section and the first check runs; a test covers both.Severity: minor
Model: fable-5-1