{"record":{"id":"17edf614c5b36c1f","repo":"openai/codex","slug":"current-time-request-was-canceled-err","errorCode":null,"errorMessage":"current-time request was canceled: {err}","messagePattern":"current-time request was canceled: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/app-server/src/current_time.rs","lineNumber":126,"sourceCode":"        .send_request_to_connections(\n            Some(&connection_ids),\n            ServerRequestPayload::CurrentTimeRead(CurrentTimeReadParams {\n                thread_id: thread_id.to_string(),\n            }),\n            /*thread_id*/ None,\n        )\n        .await;\n\n    let result = match timeout_at(deadline, rx).await {\n        Ok(Ok(Ok(result))) => result,\n        Ok(Ok(Err(err))) => {\n            bail!(\n                \"current-time request failed: code={} message={}\",\n                err.code,\n                err.message\n            );\n        }\n        Ok(Err(err)) => bail!(\"current-time request was canceled: {err}\"),\n        Err(_) => {\n            let _canceled = outgoing.cancel_request(&request_id).await;\n            bail!(\n                \"current-time request timed out after {}s\",\n                CURRENT_TIME_REQUEST_TIMEOUT.as_secs()\n            );\n        }\n    };\n    let response: CurrentTimeReadResponse =\n        serde_json::from_value(result).context(\"invalid current-time response\")?;\n\n    DateTime::from_timestamp(response.current_time_at, 0)\n        .ok_or_else(|| anyhow!(\"current-time response is outside the supported range\"))\n}\n\nfn require_single_current_time_connection(connection_ids: &[ConnectionId]) -> Result<ConnectionId> {\n    // External clocks are not interchangeable, so do not choose one silently.\n    match connection_ids {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/app-server/src/current_time.rs#L108-L144","documentation":"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.","triggerScenarios":"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).","commonSituations":"Parallel codex sessions sharing CODEX_HOME; scripted bulk history writes; history files on network filesystems with slow locking.","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."],"exampleFix":"// before\nappend_entry(&path, entry).await?;\n// after: bounded retry on contention\nlet mut attempt = 0;\nloop {\n    match append_entry(&path, entry.clone()).await {\n        Err(e) if e.kind() == std::io::ErrorKind::WouldBlock && attempt < 5 => {\n            attempt += 1;\n            tokio::time::sleep(std::time::Duration::from_millis(100 * attempt)).await;\n        }\n        r => break r?,\n    }\n}","handlingStrategy":"retry","validationCode":"fn single_writer_guard(lock_path: &std::path::Path) -> Option<fs2::File> {\n    let f = std::fs::OpenOptions::new()\n        .write(true)\n        .create(true)\n        .open(lock_path)\n        .ok()?;\n    f.try_lock_exclusive().ok().map(|_| f)\n}","typeGuard":null,"tryCatchPattern":"let mut attempt = 0;\nloop {\n    match append_entry(&path, entry.clone()).await {\n        Err(e) if e.kind() == std::io::ErrorKind::WouldBlock && attempt < 5 => {\n            attempt += 1;\n            tokio::time::sleep(std::time::Duration::from_millis(100 * attempt)).await;\n        }\n        r => break r?, // never swallow: the entry is unwritten on WouldBlock\n    }\n}","preventionTips":["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."],"tags":["file-lock","concurrency","history","wouldblock","rust"],"backgroundTag":"file-lock-contention","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}