windmill-labs/windmill · error
Cannot convert OsString to String
Error message
Cannot convert OsString to String
What it means
During Python venv postinstall, Windmill walks the site-packages directory to relink/collect package folders. Each entry's file_name() is an OsString that must be valid UTF-8 to become a Rust String; the code raises "Cannot convert OsString to String" when a directory name contains invalid UTF-8 bytes. Python package names are essentially always ASCII, so this almost always indicates a corrupted or foreign directory inside site-packages.
Source
Thrown at backend/windmill-worker/src/python_executor.rs:547
conn: &Connection,
) -> windmill_common::error::Result<()> {
// It is guranteed that additional_python_paths only contains paths within windmill/cache/
// All other paths you would usually expect in PYTHONPATH are NOT included. These are added in downstream
//
// <PackageName, Vec<GlobalPath>>
let mut lookup_table: HashMap<String, Vec<String>> = HashMap::new();
// e.g.: <"requests", ["/tmp/windmill/cache/python_311/requests==1.0.0"]>
for path in additional_python_paths.iter() {
for entry in fs::read_dir(&path)? {
let entry = entry?;
// Ignore all files, we only need directories.
// We cannot merge files.
if entry.file_type()?.is_dir() {
// Short name, e.g.: requests
let name = entry
.file_name()
.to_str()
.ok_or(anyhow::anyhow!("Cannot convert OsString to String"))?
.to_owned();
if name == "bin" || name == "__pycache__" || name.contains("dist-info") {
continue;
}
if let Some(existing_paths) = lookup_table.get_mut(&name) {
tracing::debug!(
"Found existing package name: {:?} in {}",
entry.file_name(),
path
);
existing_paths.push(path.to_owned())
} else {
lookup_table.insert(name, vec![path.to_owned()]);
}
}
}View on GitHub (pinned to e474e8803c)
Solutions
- List site-packages to find the non-UTF-8 directory: find <venv>/lib/python*/site-packages -maxdepth 1 -type d | grep -P '[^\x00-\x7F]' and delete or rename it.
- Delete the corrupted venv/cache directory so the next job reinstalls it cleanly.
- Check the S3 venv tarball (enterprise) for corrupt entries and re-upload a fresh one, or disable the tarball cache for that venv.
- Ensure the worker's locale/filesystem is UTF-8 (e.g. LANG=C.UTF-8) so tooling doesn't create mis-encoded names.
Example fix
# before (inspect)
ls <venv>/lib/python3.11/site-packages
# after (remove the corrupt entry and let it reinstall)
find <venv>/lib/python3.11/site-packages -maxdepth 1 -type d -name '*[^[:print:]]*' -exec rm -rf {} +
# or simply:
rm -rf <venv> Defensive patterns
Strategy: validation
Validate before calling
# run on the worker host before scheduling Python jobs bad=$(find /root/.cache/windmill -path '*/site-packages/*' -maxdepth 8 -type d 2>/dev/null | grep -P '[^\x00-\x7F]'); [ -z "$bad" ] && echo OK || echo "$bad"
Try / catch
// worker-side log handling: treat as cache corruption and wipe the venv
if (err.message.includes('Cannot convert OsString to String')) {
fs.rmSync(venvPath, { recursive: true, force: true }); // next job reinstalls cleanly
} Prevention
- Set LANG=C.UTF-8 on worker hosts so tooling never creates mis-encoded filenames
- Periodically validate/refresh the venv cache; delete venvs after worker crashes
- Verify S3 venv tarballs are built and extracted with UTF-8-safe tooling
When it happens
Trigger: Running a Python job whose dependency install triggers the postinstall step while a directory inside the venv's site-packages has a non-UTF-8 name (bad bytes from a failed download, a manually extracted tarball, or filenames created with a non-UTF-8 locale).
Common situations: A venv cache corrupted by disk errors or interrupted extraction; someone manually placed a folder with exotic characters into site-packages on the worker host; a shared/NFS mount with a different filesystem encoding; rebuilding worker caches from a damaged S3 tarball.
Related errors
- could not read the run of job ${id}: ${res.status} ${await r
- could not record run ${experiment_id}: ${res.status} ${await
- file path escapes the build directory: ${rel}
- ${what} failed:\n${output}
- File not found: ${filePath}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/5ade1208c09f7409.
Report an issue: GitHub.