Summary
On a clean stop, pg0 rewrites instance.json without the pid field. But start hard-requires pid when deserializing instance state, so any start after a clean stop fails with JSON error: missing field pid until instance.json is manually deleted (pg0 then regenerates it against the existing data dir).
Environment
- pg0 0.15.1 (pg0-embedded Python package), Linux, PostgreSQL 18.1.0 and 18.6.0
- Observed 2026-09-04/05 on Ubuntu; instance under
~/.pg0/instances/<name>/
Repro
pg0 start --name demo --version 18.x ... → running
pg0 stop --name demo → clean stop, no error
cat ~/.pg0/instances/demo/instance.json → JSON has port, data_dir, etc. but no pid key
pg0 start --name demo ... → error: missing field pid (deserialization), nonzero exit
Amplifying factors
- Under systemd
Restart=on-failure this becomes a tight restart loop: every start fails → the unit restarts every few seconds (we observed 83 consecutive failed restarts during an unrelated crash recovery; PostgreSQL had no listener the whole time).
- Related pid-field edge cases hit the same crash family:
pid: null → JSON deserialization crash; pid: 0 → misdetected as running via kill(0) semantics. Deleting instance.json and letting pg0 regenerate it is the only clean recovery.
Expected
Either stop leaves instance.json in a state start accepts (e.g. omit-able pid with #[serde(default)]), or start tolerates a stopped-state instance.json when the data dir exists.
Workaround we shipped (for reference)
A systemd ExecStartPre guard: if instance.json exists but lacks "pid", delete it before start (validated safe against an existing data dir).
Summary
On a clean
stop, pg0 rewritesinstance.jsonwithout thepidfield. Butstarthard-requirespidwhen deserializing instance state, so any start after a clean stop fails withJSON error: missing field piduntilinstance.jsonis manually deleted (pg0 then regenerates it against the existing data dir).Environment
~/.pg0/instances/<name>/Repro
pg0 start --name demo --version 18.x ...→ runningpg0 stop --name demo→ clean stop, no errorcat ~/.pg0/instances/demo/instance.json→ JSON hasport,data_dir, etc. but nopidkeypg0 start --name demo ...→ error:missing field pid(deserialization), nonzero exitAmplifying factors
Restart=on-failurethis becomes a tight restart loop: every start fails → the unit restarts every few seconds (we observed 83 consecutive failed restarts during an unrelated crash recovery; PostgreSQL had no listener the whole time).pid: null→ JSON deserialization crash;pid: 0→ misdetected as running viakill(0)semantics. Deletinginstance.jsonand letting pg0 regenerate it is the only clean recovery.Expected
Either
stopleavesinstance.jsonin a statestartaccepts (e.g. omit-ablepidwith#[serde(default)]), orstarttolerates a stopped-stateinstance.jsonwhen the data dir exists.Workaround we shipped (for reference)
A systemd
ExecStartPreguard: ifinstance.jsonexists but lacks"pid", delete it before start (validated safe against an existing data dir).