Hmbown/CodeWhale · error · anyhow::Error
Persistent service {id} lost its process id
Error message
Persistent service {id} lost its process id What it means
After removing a service from the map, commit re-reads the child's pid to unregister the pending persistent process group and fill the `PersistentServiceReceipt`. The pid existed during the validation loop, so this error means it disappeared between the two loops — the child was reaped mid-commit. The handoff aborts because the process-group registration could not be cleaned up for that pid.
Source
Thrown at crates/tui/src/tools/shell.rs:2912
.is_none()
{
return Err(anyhow!(
"Persistent service {id} has no releasable process id"
));
}
}
let mut receipts = Vec::with_capacity(ids.len());
for id in ids {
let mut shell = self
.processes
.remove(&id)
.ok_or_else(|| anyhow!("Persistent service {id} disappeared during commit"))?;
let pid = shell
.child
.as_ref()
.and_then(ShellChild::process_id)
.ok_or_else(|| anyhow!("Persistent service {id} lost its process id"))?;
unregister_pending_persistent_process_group(pid);
shell.ownership = ShellOwnership::Released;
shell.stdin = None;
shell.heavy_permit.take();
shell.work_lifecycle = None;
receipts.push(PersistentServiceReceipt {
task_id: id,
pid,
process_group_id: pid,
ownership: "external".to_string(),
});
}
Ok(receipts)
}
/// Kill only services waiting for a successful exec ownership transfer.
/// Ordinary background jobs retain their existing manager lifetime.
pub fn abort_persistent_services(&mut self) {View on GitHub (pinned to 0c42157ee5)
Solutions
- Treat as an internal bug: capture the task_id and reproduction steps
- Ensure nothing reaps or mutates manager children while commit runs
- After the failure, check for a lingering registered persistent process group for that service
Defensive patterns
Strategy: try-catch
Try / catch
match manager.commit_persistent_services() {
Ok(receipts) => receipts,
Err(err) if err.to_string().contains("lost its process id") => {
// pid vanished between commit loops: check for a lingering registered
// persistent process group, then report as an internal bug
}
Err(err) => return Err(err),
} Prevention
- Prevent concurrent reaping or mutation of manager children during commit
- Verify no orphaned pending-persistent process group remains after this failure
- Capture the task_id when reporting
- Keep commit single-threaded with respect to the whole manager
When it happens
Trigger: The child handle of a PersistPending shell losing its process id between commit's validation pass and its removal pass (reaping or handle teardown interleaved with commit).
Common situations: Same shape as the other mid-commit invariants: concurrent manager mutation or reaping; rare in single-threaded production use.
Related errors
- Persistent service {id} has no releasable process id
- Persistent service {id} disappeared before commit
- Persistent service {id} disappeared during commit
- Persistent service {id} exited before ownership transfer (st
- snapshot dir has no parent
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/825d7b1f78f6f318.
Report an issue: GitHub.