openai/codex · error · anyhow::Error
current-time request was canceled: {err}
Error message
current-time request was canceled: {err} What it means
append_entry takes the exclusive lock with bounded retries plus RETRY_SLEEP backoff; if another writer holds the lock through the whole window the append fails with ErrorKind::WouldBlock (codex-rs/message-history/src/lib.rs:181). The entry is NOT written when this fires — callers must retry or explicitly drop it; treating the error as success silently loses history.
Source
Thrown at codex-rs/app-server/src/current_time.rs:126
.send_request_to_connections(
Some(&connection_ids),
ServerRequestPayload::CurrentTimeRead(CurrentTimeReadParams {
thread_id: thread_id.to_string(),
}),
/*thread_id*/ None,
)
.await;
let result = match timeout_at(deadline, rx).await {
Ok(Ok(Ok(result))) => result,
Ok(Ok(Err(err))) => {
bail!(
"current-time request failed: code={} message={}",
err.code,
err.message
);
}
Ok(Err(err)) => bail!("current-time request was canceled: {err}"),
Err(_) => {
let _canceled = outgoing.cancel_request(&request_id).await;
bail!(
"current-time request timed out after {}s",
CURRENT_TIME_REQUEST_TIMEOUT.as_secs()
);
}
};
let response: CurrentTimeReadResponse =
serde_json::from_value(result).context("invalid current-time response")?;
DateTime::from_timestamp(response.current_time_at, 0)
.ok_or_else(|| anyhow!("current-time response is outside the supported range"))
}
fn require_single_current_time_connection(connection_ids: &[ConnectionId]) -> Result<ConnectionId> {
// External clocks are not interchangeable, so do not choose one silently.
match connection_ids {View on GitHub (pinned to 339751715c)
Solutions
- Retry the append once the contention window passes — the entry is still pending, not persisted.
- Enforce a single writer per history file (per user or per session).
- Lower the max-bytes cap so in-place trims finish quickly.
- Move the history file off network storage.
Example fix
// before
append_entry(&path, entry).await?;
// after: bounded retry on contention
let mut attempt = 0;
loop {
match append_entry(&path, entry.clone()).await {
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock && attempt < 5 => {
attempt += 1;
tokio::time::sleep(std::time::Duration::from_millis(100 * attempt)).await;
}
r => break r?,
}
} Defensive patterns
Strategy: retry
Validate before calling
fn single_writer_guard(lock_path: &std::path::Path) -> Option<fs2::File> {
let f = std::fs::OpenOptions::new()
.write(true)
.create(true)
.open(lock_path)
.ok()?;
f.try_lock_exclusive().ok().map(|_| f)
} Try / catch
let mut attempt = 0;
loop {
match append_entry(&path, entry.clone()).await {
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock && attempt < 5 => {
attempt += 1;
tokio::time::sleep(std::time::Duration::from_millis(100 * attempt)).await;
}
r => break r?, // never swallow: the entry is unwritten on WouldBlock
}
} Prevention
- Run a single writer per history file; queue appends through one process.
- Retry WouldBlock from append_entry — the entry was not persisted.
- Keep history files local and under the size cap to shorten lock holds.
When it happens
Trigger: Two processes or threads calling append_entry on the same history file concurrently, with one keeping the lock past the retry budget (large trim under the max_bytes cap, slow or network storage).
Common situations: Parallel codex sessions sharing CODEX_HOME; scripted bulk history writes; history files on network filesystems with slow locking.
Related errors
- current-time request failed: code={} message={}
- mutex poisoned
- WouldBlock
- Unsupported platform: ${platform} (${arch})
- Unsupported target triple: ${targetTriple}
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/17edf614c5b36c1f.
Report an issue: GitHub.