{"record":{"id":"4579b59c0f09de76","repo":"windmill-labs/windmill","slug":"uv-pip-install-was-canceled","errorCode":null,"errorMessage":"uv pip install was canceled","messagePattern":"uv pip install was canceled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"backend/windmill-worker/src/python_executor.rs","lineNumber":3041,"sourceCode":"                {\n                  tracing::error!(\n                      req = %req,\n                      \"Failed to create oom_score_adj for python dependency installation process: {e}\"\n                  );\n                }\n            } else {\n                tracing::error!(\n                    workspace_id = %w_id,\n                    \"Index out of range for uv pids\",\n                );\n            }\n\n            tokio::select! {\n                // Canceled\n                _ = kill_rx.recv() => {\n                    Box::into_pin(uv_install_proccess.kill()).await?;\n                    pids.lock().await.get_mut(i).and_then(|e| e.take());\n                    return Err(Error::from(anyhow::anyhow!(\"uv pip install was canceled\")));\n                },\n                (_, _, exitstatus) = async {\n                    // See tokio::process::Child::wait_with_output() for more context\n                    // Sometimes uv_install_proccess.wait() is not exiting if stderr is not awaited first\n                    (stderr_future.await, stdout_future.await, Box::into_pin(uv_install_proccess.wait()).await)\n                } => match exitstatus {\n                    Ok(status) => if !status.success() {\n                        #[cfg(unix)]\n                        let code = status.signal();\n                        #[cfg(not(unix))]\n                        let code = status.code();\n\n                        tracing::warn!(\n                            workspace_id = %w_id,\n                            \"uv install {} did not succeed, exit status: {:?}\",\n                            &req,\n                            code\n                        );","sourceCodeStart":3023,"sourceCodeEnd":3059,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/python_executor.rs#L3023-L3059","documentation":"While `uv pip install` runs, handle_python_reqs selects between the job's kill_rx channel and a future awaiting the child's stderr/stdout pipes and exit status. If kill_rx fires first (the job was canceled), the code kills the uv process, removes its tracked pid, and returns \"uv pip install was canceled\". It is a deliberate cooperative-cancellation message, not an install failure.","triggerScenarios":"A Python dependency installation is canceled while uv is actively running: user stops the job, a flow is canceled mid-step, a per-job timeout expires, or the worker is draining and cancels queued/running installs.","commonSituations":"Canceling a script whose first run needs a big requirements install; flow timeouts smaller than the install duration; duplicated runs stopped after one succeeds; operator kills a stuck run during dependency resolution.","solutions":["If the cancel was intentional, just rerun the job — the venv lock and cache make the next install resume/reuse work.","Trim or pin requirements (use a lockfile/wheel cache) so installs finish well inside timeouts.","Raise the step/job timeout if long installs are routinely being killed.","Check for repeated spurious cancellations (worker restarts, flow engine bugs) in worker logs."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await runPythonStep();\n} catch (e) {\n  if (String(e.message).includes('uv pip install was canceled')) {\n    return await runPythonStep(); // partial install resumes from cache\n  }\n  throw e;\n}","preventionTips":["Size job/step timeouts to exceed realistic uv install durations","Use lockfiles and a wheel cache so installs complete quickly","Don't cancel-and-restart jobs during their first dependency install unless necessary; uv's cache makes reruns cheap"],"tags":["python","cancellation","subprocess","uv"],"backgroundTag":"operation-canceled","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}