tinyhumansai/openhuman · error · SubmitError

flushing pool job request

Error message

flushing pool job request

What it means

Flushing the worker's stdin after writing the job line failed — the newline-terminated request was buffered but never delivered. Like the write error it is a pre-submit failure: the worker did not receive the job, so the caller may discard this worker and resubmit elsewhere without risking duplicate execution.

Source

Thrown at src/openhuman/runtime/pool/worker.rs:235

    /// 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 {
                    Ok(inner) => inner,
                    Err(_) => {
                        return Err(SubmitError::post(anyhow::anyhow!(
                            "pool worker job timed out (hard deadline; worker wedged)"
                        )))
                    }
                },
                None => self.responses.next_line().await,
            };
            let line = match next {

View on GitHub (pinned to 7491200858)

Solutions

  1. Treat the worker as unusable and resubmit the job to a new worker
  2. Investigate the worker process state (broken pipe means it exited; check crash logs)
  3. Reduce pool worker lifetime or add liveness pings to detect half-dead workers early
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/openhuman/runtime/pool/worker.rs:235 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/c778511dbe0b9783. Report an issue: GitHub.