windmill-labs/windmill · error · ValueError
preprocessor function is missing
Error message
preprocessor function is missing
What it means
backend/windmill-worker/src/python_executor.rs builds a Python wrapper for the job. When the job has a preprocessor expansion (pre_spread), the generated wrapper checks inner_script.preprocessor; if it is None or not callable it raises ValueError('preprocessor function is missing'). This happens when preprocessor args are supplied but the script itself defines no usable preprocessor function.
Source
Thrown at backend/windmill-worker/src/python_executor.rs:812
job.preprocessed,
job.script_entrypoint_override.as_deref(),
inner_content,
&script_path,
&temp_script_refs,
)
.await?;
tracing::debug!("Finished preparing wrapper");
let apply_preprocessor = pre_spread.is_some();
create_args_and_out_file(&client, job, job_dir, conn).await?;
tracing::debug!("Finished preparing wrapper");
let preprocessor = if let Some(pre_spread) = pre_spread {
format!(
r#"if inner_script.preprocessor is None or not callable(inner_script.preprocessor):
raise ValueError("preprocessor function is missing")
else:
pre_args = {{}}
{pre_spread}
for k, v in list(pre_args.items()):
if v == '<function call>':
del pre_args[k]
kwargs = inner_script.preprocessor(**pre_args)
kwrags_json = res_to_json(kwargs, type(kwargs))
with open("args.json", 'w') as f:
f.write(kwrags_json)"#
)
} else {
"".to_string()
};
let postprocessor = get_result_postprocessor(annotations.skip_result_postprocessing);
let os_main_override = if let Some(main_override) = main_name.as_ref() {View on GitHub (pinned to e474e8803c)
Solutions
- Open the script and define a callable preprocessor function (the wrapper requires inner_script.preprocessor to be callable)
- Remove the preprocessor inputs/args from the job or step if preprocessing is no longer needed
- Re-save/redeploy the script so the deployed version matches the flow step's expectations
- Inspect '<function call>' placeholder handling: args whose value equals that marker are deleted, ensure you are not passing raw placeholders expecting a preprocessor to consume them
Example fix
# before: script has no preprocessor but step passes preprocessor args
# after: add to the script
def preprocessor(args):
... # transform args
return args Defensive patterns
Strategy: validation
Validate before calling
# before deploying/running a job that uses preprocessor args assert callable(getattr(script, 'preprocessor', None)), "script must define a callable preprocessor"
Type guard
def has_callable_preprocessor(script) -> bool:
pre = getattr(script, 'preprocessor', None)
return callable(pre) Try / catch
try {
runJob(payload)
} catch (e) {
if (String(e).includes('preprocessor function is missing')) {
// redeploy the script with a preprocessor or drop the preprocessor args
} else { throw e }
} Prevention
- Never remove a preprocessor definition while the step still passes preprocessor args
- Validate the deployed script's preprocessor field when saving
- Keep flow steps and script versions in sync after refactors
- Add a lint/CI check that scripts consuming preprocessor args define a callable preprocessor
When it happens
Trigger: A job runs with preprocessor-related arguments (pre_spread present) but the deployed script's preprocessor field is None or not callable — e.g. the script was saved without a preprocessor, or its preprocessor was set to a non-function value.
Common situations: Editing a script and dropping the preprocessor definition while keeping preprocessor inputs; a preprocessor step removed/replaced upstream but the job payload still requests preprocessing; desync between script version and the flow step that passes preprocessor args.
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}
- preprocessor function is missing
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/0fcd7d13ea301644.
Report an issue: GitHub.