tinyhumansai/openhuman · error · SubmitError
serialising pool job
Error message
serialising pool job
What it means
Serialising the PoolJobRequest to a JSON line failed before it could be written to the worker's stdin. This is a SubmitError::pre (pre-write) — the job never reached the worker, so the worker's stdio framing is still trustworthy and the job may be resubmitted to (this or another) worker. serde failure here means the request contains a value that cannot be represented in JSON.
Source
Thrown at src/openhuman/runtime/pool/worker.rs:225
responses: lines,
jobs_done: 0,
last_used: Instant::now(),
})
}
/// Submit one job and await its response.
///
/// `hard_timeout` is a **safety net** above the worker's own soft deadline:
/// the worker aborts a job at `req.timeout_ms` and still replies, so this
/// only fires if the worker itself has wedged. On `Err` the caller must
/// discard this worker — its stdio framing can no longer be trusted.
pub async fn submit(
&mut self,
req: &PoolJobRequest,
hard_timeout: Option<Duration>,
) -> std::result::Result<PoolJobResponse, SubmitError> {
let mut line = serde_json::to_string(req)
.map_err(|e| SubmitError::pre(anyhow::Error::new(e).context("serialising pool job")))?;
line.push('\n');
// A write failure means the bytes never reached the worker (e.g. a
// reused idle worker died) → the job did not run → safe to retry.
self.stdin.write_all(line.as_bytes()).await.map_err(|e| {
SubmitError::pre(anyhow::Error::new(e).context("writing pool job request"))
})?;
// Past this point the request bytes are in the pipe: the job may execute,
// so any later failure is terminal (never re-run the same job).
self.stdin.flush().await.map_err(|e| {
SubmitError::post(anyhow::Error::new(e).context("flushing pool job request"))
})?;
// Fixed deadline: `continue`ing over unparseable / mismatched-id lines
// must NOT reset the wedged-worker timeout, so it bounds the total wait.
let deadline = hard_timeout.map(|t| tokio::time::Instant::now() + t);
loop {
let next = match deadline {
Some(dl) => match tokio::time::timeout_at(dl, self.responses.next_line()).await {View on GitHub (pinned to 7491200858)
Solutions
- Inspect the PoolJobRequest fields for non-serializable values (e.g. non-string map keys, NaN floats) and sanitize them before submit
- Add explicit serialization tests for the job type if a new field was added without serde attributes
- If caused by a type change, version the pool protocol so worker and pool agree
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/openhuman/runtime/pool/worker.rs:225 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/f93d3f424cc67676.
Report an issue: GitHub.