affaan-m/ECC · error
DB writer acknowledgement dropped
Error message
DB writer acknowledgement dropped
What it means
Sent when the oneshot ack channel is dropped before a result arrives — i.e. the DB writer task terminated mid-operation (panic, early return on open failure) without sending Ok/Err. Unlike 'channel closed' (send failed), here the message was delivered but the reply never came.
Solutions
- Restart the session runtime to spawn a fresh DB writer
- Investigate the writer's open_error / session stderr log for the underlying open or panic cause
- Add a fallback timeout on ack_rx.await so callers fail fast with context
Example fix
// before
match ack_rx.await { ... Err(_) => Err(anyhow::anyhow!("DB writer acknowledgement dropped")) }
// after
match tokio::time::timeout(Duration::from_secs(10), ack_rx).await {
Ok(Ok(Ok(()))) => Ok(()),
Ok(Ok(Err(e))) => Err(anyhow::anyhow!(e)),
Ok(Err(_)) | Err(_) => Err(anyhow::anyhow!("DB writer acknowledgement dropped or timed out")),
} Defensive patterns
Strategy: try-catch
Validate before calling
if db_writer.is_closed() {
anyhow::bail!("writer already terminated; acks will never arrive");
} Try / catch
match db_writer.update_pid(pid).await {
Err(e) if e.to_string().contains("acknowledgement dropped") => {
eprintln!("DB writer died mid-write; check session stderr log and restart runtime");
}
Err(e) => return Err(e),
Ok(()) => (),
} Prevention
- Add a timeout around ack awaits to fail fast
- Log writer panics with catch_unwind/JoinHandle inspection
- Validate the DB opens successfully before starting the writer loop
When it happens
Trigger: run_db_writer task panics while processing the message, or exits after StateStore::open fails and drops rx/ack_tx without acking pending messages.
Common situations: Unreadable/corrupt session DB causing writer startup abort; panic inside the write path; process shutting down and aborting the writer task.
Related errors
- DB writer channel closed
- an active harness configuration already exists
- atomic promotion compare-and-swap failed
- atomic rollback compare-and-swap failed
- baseline is not the active harness configuration
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/7e3b09c68c633b99.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/runtime.rs:76
}
async fn touch_heartbeat(&self) -> Result<()> {
self.send(|ack| DbMessage::TouchHeartbeat { ack }).await
}
async fn send<F>(&self, build: F) -> Result<()>
where
F: FnOnce(oneshot::Sender<DbAck>) -> DbMessage,
{
let (ack_tx, ack_rx) = oneshot::channel();
self.tx
.send(build(ack_tx))
.map_err(|_| anyhow::anyhow!("DB writer channel closed"))?;
match ack_rx.await {
Ok(Ok(())) => Ok(()),
Ok(Err(error)) => Err(anyhow::anyhow!(error)),
Err(_) => Err(anyhow::anyhow!("DB writer acknowledgement dropped")),
}
}
}
fn run_db_writer(db_path: PathBuf, session_id: String, mut rx: mpsc::UnboundedReceiver<DbMessage>) {
let (opened, open_error) = match StateStore::open(&db_path) {
Ok(db) => (Some(db), None),
Err(error) => (None, Some(error.to_string())),
};
while let Some(message) = rx.blocking_recv() {
match message {
DbMessage::UpdateState { state, ack } => {
let result = match opened.as_ref() {
Some(db) => db
.update_state(&session_id, &state)
.map_err(|error| error.to_string()),
None => Err(open_errorView on GitHub (pinned to 8321021c54)